diff --git a/bin/ruby-build b/bin/ruby-build
index 1a5dc68a..42361fcd 100755
--- a/bin/ruby-build
+++ b/bin/ruby-build
@@ -166,14 +166,31 @@ make_package() {
   popd >&4
 }
 
+compute_sha2() {
+  local output
+  if type shasum &>/dev/null; then
+    output="$(shasum -a 256 -b)" || return 1
+    echo "${output% *}"
+  elif type openssl &>/dev/null; then
+    output="$(openssl dgst -sha256)" || return 1
+    echo "${output##* }"
+  elif type sha256sum &>/dev/null; then
+    output="$(sha256sum --quiet)" || return 1
+    echo "${output% *}"
+  else
+    return 1
+  fi
+}
+
 compute_md5() {
+  local output
   if type md5 &>/dev/null; then
     md5 -q
   elif type openssl &>/dev/null; then
-    local output="$(openssl md5)"
+    output="$(openssl md5)" || return 1
     echo "${output##* }"
   elif type md5sum &>/dev/null; then
-    local output="$(md5sum -b)"
+    output="$(md5sum -b)" || return 1
     echo "${output% *}"
   else
     return 1
@@ -181,8 +198,8 @@ compute_md5() {
 }
 
 verify_checksum() {
-  # If there's no MD5 support, return success
-  [ -n "$HAS_MD5_SUPPORT" ] || return 0
+  # If there's no SHA2 support, return success
+  [ -n "$HAS_SHA2_SUPPORT" ] || return 0
 
   # If the specified filename doesn't exist, return success
   local filename="$1"
@@ -193,7 +210,7 @@ verify_checksum() {
   [ -n "$expected_checksum" ] || return 0
 
   # If the computed checksum is empty, return failure
-  local computed_checksum=`echo "$(compute_md5 < "$filename")" | tr [A-Z] [a-z]`
+  local computed_checksum=`echo "$(compute_sha2 < "$filename")" | tr [A-Z] [a-z]`
   [ -n "$computed_checksum" ] || return 1
 
   if [ "$expected_checksum" != "$computed_checksum" ]; then
@@ -983,10 +1000,10 @@ if [ -n "$RUBY_BUILD_SKIP_MIRROR" ]; then
   unset RUBY_BUILD_MIRROR_URL
 fi
 
-if echo test | compute_md5 >/dev/null; then
-  HAS_MD5_SUPPORT=1
+if echo test | compute_sha2 >/dev/null; then
+  HAS_SHA2_SUPPORT=1
 else
-  unset HAS_MD5_SUPPORT
+  unset HAS_SHA2_SUPPORT
   unset RUBY_BUILD_MIRROR_URL
 fi
 
diff --git a/script/mirror b/script/mirror
index d0e1088e..17c512df 100755
--- a/script/mirror
+++ b/script/mirror
@@ -11,8 +11,8 @@ test_mirrored() {
   curl -qsSfIL "$RUBY_BUILD_MIRROR_URL/$1" >/dev/null 2>&1
 }
 
-compute_md5() {
-  local output="$(openssl md5)"
+compute_sha2() {
+  local output="$(openssl dgst -sha256)"
   echo "${output##* }" | tr '[A-Z]' '[a-z]'
 }
 
@@ -26,7 +26,7 @@ download_and_verify() {
   local file="$2"
   local expected="$3"
   download_package "$url" "$file"
-  checksum="$(compute_md5 < "$file")"
+  checksum="$(compute_sha2 < "$file")"
   if [ "$checksum" != "$expected" ]; then
     echo "Error: $url doesn't match its checksum $expected" >&2
     return 1
diff --git a/test/cache.bats b/test/cache.bats
index 8819facf..5dd712a0 100644
--- a/test/cache.bats
+++ b/test/cache.bats
@@ -10,7 +10,7 @@ setup() {
 
 
 @test "packages are saved to download cache" {
-  stub md5 true
+  stub shasum true
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/without-checksum
@@ -18,12 +18,12 @@ setup() {
   [ -e "${RUBY_BUILD_CACHE_PATH}/package-1.0.0.tar.gz" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "cached package without checksum" {
-  stub md5 true
+  stub shasum true
   stub curl
 
   cp "${FIXTURE_ROOT}/package-1.0.0.tar.gz" "$RUBY_BUILD_CACHE_PATH"
@@ -33,12 +33,12 @@ setup() {
   [ -e "${RUBY_BUILD_CACHE_PATH}/package-1.0.0.tar.gz" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "cached package with valid checksum" {
-  stub md5 true "echo 83e6d7725e20166024a1eb74cde80677"
+  stub shasum true "echo ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   stub curl
 
   cp "${FIXTURE_ROOT}/package-1.0.0.tar.gz" "$RUBY_BUILD_CACHE_PATH"
@@ -49,15 +49,15 @@ setup() {
   [ -e "${RUBY_BUILD_CACHE_PATH}/package-1.0.0.tar.gz" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "cached package with invalid checksum falls back to mirror and updates cache" {
   export RUBY_BUILD_SKIP_MIRROR=
-  local checksum="83e6d7725e20166024a1eb74cde80677"
+  local checksum="ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
 
-  stub md5 true "echo invalid" "echo $checksum"
+  stub shasum true "echo invalid" "echo $checksum"
   stub curl "-*I* : true" \
     "-q -o * -*S* http://?*/$checksum : cp $FIXTURE_ROOT/package-1.0.0.tar.gz \$3"
 
@@ -70,12 +70,12 @@ setup() {
   diff -q "${RUBY_BUILD_CACHE_PATH}/package-1.0.0.tar.gz" "${FIXTURE_ROOT}/package-1.0.0.tar.gz"
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "nonexistent cache directory is ignored" {
-  stub md5 true
+  stub shasum true
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   export RUBY_BUILD_CACHE_PATH="${TMP}/nonexistent"
@@ -86,5 +86,5 @@ setup() {
   [ ! -d "$RUBY_BUILD_CACHE_PATH" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
diff --git a/test/checksum.bats b/test/checksum.bats
index 5bdbf1d5..e89c2610 100644
--- a/test/checksum.bats
+++ b/test/checksum.bats
@@ -6,7 +6,7 @@ export RUBY_BUILD_CACHE_PATH=
 
 
 @test "package URL without checksum" {
-  stub md5 true
+  stub shasum true
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/without-checksum
@@ -14,12 +14,12 @@ export RUBY_BUILD_CACHE_PATH=
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "package URL with valid checksum" {
-  stub md5 true "echo 83e6d7725e20166024a1eb74cde80677"
+  stub shasum true "echo ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/with-checksum
@@ -27,12 +27,12 @@ export RUBY_BUILD_CACHE_PATH=
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "package URL with invalid checksum" {
-  stub md5 true "echo 83e6d7725e20166024a1eb74cde80677"
+  stub shasum true "echo ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/with-invalid-checksum
@@ -40,12 +40,12 @@ export RUBY_BUILD_CACHE_PATH=
   [ ! -f "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
-@test "package URL with checksum but no MD5 support" {
-  stub md5 false
+@test "package URL with checksum but no shasum support" {
+  stub shasum false
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/with-checksum
@@ -53,12 +53,12 @@ export RUBY_BUILD_CACHE_PATH=
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "package with invalid checksum" {
-  stub md5 true "echo invalid"
+  stub shasum true "echo invalid"
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/with-checksum
@@ -66,11 +66,11 @@ export RUBY_BUILD_CACHE_PATH=
   [ ! -f "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 @test "existing tarball in build location is reused" {
-  stub md5 true "echo 83e6d7725e20166024a1eb74cde80677"
+  stub shasum true "echo ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   stub curl false
   stub wget false
 
@@ -81,19 +81,19 @@ export RUBY_BUILD_CACHE_PATH=
   ln -s "${FIXTURE_ROOT}/package-1.0.0.tar.gz" "$RUBY_BUILD_BUILD_PATH"
 
   run_inline_definition <<DEF
-install_package "package-1.0.0" "http://example.com/packages/package-1.0.0.tar.gz#83e6d7725e20166024a1eb74cde80677" copy
+install_package "package-1.0.0" "http://example.com/packages/package-1.0.0.tar.gz#ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5" copy
 DEF
 
   assert_success
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
-  unstub md5
+  unstub shasum
 }
 
 @test "existing tarball in build location is discarded if not matching checksum" {
-  stub md5 true \
+  stub shasum true \
     "echo invalid" \
-    "echo 83e6d7725e20166024a1eb74cde80677"
+    "echo ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   export -n RUBY_BUILD_CACHE_PATH
@@ -103,11 +103,11 @@ DEF
   touch "${RUBY_BUILD_BUILD_PATH}/package-1.0.0.tar.gz"
 
   run_inline_definition <<DEF
-install_package "package-1.0.0" "http://example.com/packages/package-1.0.0.tar.gz#83e6d7725e20166024a1eb74cde80677" copy
+install_package "package-1.0.0" "http://example.com/packages/package-1.0.0.tar.gz#ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5" copy
 DEF
 
   assert_success
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
-  unstub md5
+  unstub shasum
 }
diff --git a/test/fixtures/definitions/with-checksum b/test/fixtures/definitions/with-checksum
index 03fe65a2..11f23580 100644
--- a/test/fixtures/definitions/with-checksum
+++ b/test/fixtures/definitions/with-checksum
@@ -1 +1 @@
-install_package "package-1.0.0" "http://example.com/packages/package-1.0.0.tar.gz#83e6d7725e20166024a1eb74cde80677" copy
+install_package "package-1.0.0" "http://example.com/packages/package-1.0.0.tar.gz#ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5" copy
diff --git a/test/mirror.bats b/test/mirror.bats
index 96571de0..abdacc44 100644
--- a/test/mirror.bats
+++ b/test/mirror.bats
@@ -7,7 +7,7 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
 
 
 @test "package URL without checksum bypasses mirror" {
-  stub md5 true
+  stub shasum true
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/without-checksum
@@ -16,12 +16,12 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
-@test "package URL with checksum but no MD5 support bypasses mirror" {
-  stub md5 false
+@test "package URL with checksum but no shasum support bypasses mirror" {
+  stub shasum false
   stub curl "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
   install_fixture definitions/with-checksum
@@ -29,15 +29,15 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "package URL with checksum hits mirror first" {
-  local checksum="83e6d7725e20166024a1eb74cde80677"
+  local checksum="ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   local mirror_url="${RUBY_BUILD_MIRROR_URL}/$checksum"
 
-  stub md5 true "echo $checksum"
+  stub shasum true "echo $checksum"
   stub curl "-*I* $mirror_url : true" \
     "-q -o * -*S* $mirror_url : cp $FIXTURE_ROOT/package-1.0.0.tar.gz \$3"
 
@@ -46,15 +46,15 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "package is fetched from original URL if mirror download fails" {
-  local checksum="83e6d7725e20166024a1eb74cde80677"
+  local checksum="ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   local mirror_url="${RUBY_BUILD_MIRROR_URL}/$checksum"
 
-  stub md5 true "echo $checksum"
+  stub shasum true "echo $checksum"
   stub curl "-*I* $mirror_url : false" \
     "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
 
@@ -63,15 +63,15 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "package is fetched from original URL if mirror download checksum is invalid" {
-  local checksum="83e6d7725e20166024a1eb74cde80677"
+  local checksum="ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
   local mirror_url="${RUBY_BUILD_MIRROR_URL}/$checksum"
 
-  stub md5 true "echo invalid" "echo $checksum"
+  stub shasum true "echo invalid" "echo $checksum"
   stub curl "-*I* $mirror_url : true" \
     "-q -o * -*S* $mirror_url : cp $FIXTURE_ROOT/package-1.0.0.tar.gz \$3" \
     "-q -o * -*S* http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$3"
@@ -82,15 +82,15 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }
 
 
 @test "default mirror URL" {
   export RUBY_BUILD_MIRROR_URL=
-  local checksum="83e6d7725e20166024a1eb74cde80677"
+  local checksum="ba988b1bb4250dee0b9dd3d4d722f9c64b2bacfc805d1b6eba7426bda72dd3c5"
 
-  stub md5 true "echo $checksum"
+  stub shasum true "echo $checksum"
   stub curl "-*I* : true" \
     "-q -o * -*S* http://?*/$checksum : cp $FIXTURE_ROOT/package-1.0.0.tar.gz \$3" \
 
@@ -99,5 +99,5 @@ export RUBY_BUILD_MIRROR_URL=http://mirror.example.com
   [ -x "${INSTALL_ROOT}/bin/package" ]
 
   unstub curl
-  unstub md5
+  unstub shasum
 }