AWS Security ChangesHomeSearch

AWS AmazonCloudFront documentation change

Service: AmazonCloudFront · 2026-04-01 · Documentation medium

File: AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.md

Summary

Added SHA256 signing example for CloudFront signed URLs and restructured notes section to include SHA256 support information

Security assessment

This change adds documentation about using SHA256 instead of SHA1 for signing CloudFront URLs, which is a security best practice. SHA1 is cryptographically weak and deprecated, so promoting SHA256 improves security. However, there's no evidence this addresses a specific security incident - it's proactive security documentation improvement.

Diff

diff --git a/AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.md b/AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.md
index 8d3a12587..daf0aa436 100644
--- a//AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.md
+++ b//AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.md
@@ -11 +11,6 @@ For more examples, see [Create signed URLs and cookies using an AWS SDK](https:/
-###### Note
+###### Notes
+
+  * Creating a signed URL is just one part of the process of [serving private content with CloudFront](./PrivateContent.html). For more information about the entire process, see [Use signed URLs](./private-content-signed-urls.html).
+
+  * In the `Signature.getInstance` call, note that `SHA1withRSA` can be replaced with `SHA256withRSA`.
+
@@ -13 +17,0 @@ For more examples, see [Create signed URLs and cookies using an AWS SDK](https:/
-Creating a signed URL is just one part of the process of [serving private content with CloudFront](./PrivateContent.html). For more information about the entire process, see [Use signed URLs](./private-content-signed-urls.html).
@@ -15 +18,0 @@ Creating a signed URL is just one part of the process of [serving private conten
-The following example shows how to create a CloudFront signed URL.
@@ -48,0 +52,70 @@ The following example shows how to create a CloudFront signed URL.
+###### Example Canned Policy Signing with SHA256 in Java
+    
+    
+    package org.example;
+    
+    import java.io.File;
+    import java.nio.file.Files;
+    import java.security.KeyFactory;
+    import java.security.PrivateKey;
+    import java.security.Signature;
+    import java.security.spec.PKCS8EncodedKeySpec;
+    import java.time.Instant;
+    import java.time.temporal.ChronoUnit;
+    import java.util.Base64;
+    
+    public class Main {
+    
+        public static void main(String[] args) throws Exception {
+            String resourceUrl = "https://a1b2c3d4e5f6g7.cloudfront.net/myfile.html";
+            String keyPairId = "K1UA3WV15I7JSD";
+            Instant expiration = Instant.now().plus(7, ChronoUnit.DAYS);
+            PrivateKey privateKey = loadPrivateKey("/path/to/private_key.der");
+    
+            System.out.println(createSignedUrl(resourceUrl, keyPairId, privateKey, expiration, "SHA1"));
+            System.out.println(createSignedUrl(resourceUrl, keyPairId, privateKey, expiration, "SHA256"));
+        }
+    
+        static String createSignedUrl(String resourceUrl, String keyPairId,
+                                      PrivateKey privateKey, Instant expiration,
+                                      String hashAlgorithm) throws Exception {
+            long epochSeconds = expiration.getEpochSecond();
+    
+            String policy = "{\"Statement\":[{\"Resource\":\"" + resourceUrl
+                    + "\",\"Condition\":{\"DateLessThan\":{\"AWS:EpochTime\":" + epochSeconds + "}}}]}";
+    
+            String jcaAlgorithm = hashAlgorithm.equals("SHA256") ? "SHA256withRSA" : "SHA1withRSA";
+    
+            Signature sig = Signature.getInstance(jcaAlgorithm);
+            sig.initSign(privateKey);
+            sig.update(policy.getBytes("UTF-8"));
+            String signature = base64UrlEncode(sig.sign());
+    
+            String url = resourceUrl
+                    + (resourceUrl.contains("?") ? "&" : "?")
+                    + "Expires=" + epochSeconds
+                    + "&Signature=" + signature
+                    + "&Key-Pair-Id=" + keyPairId;
+    
+            if (hashAlgorithm.equals("SHA256")) {
+                url += "&Hash-Algorithm=SHA256";
+            }
+    
+            return url;
+        }
+    
+        static String base64UrlEncode(byte[] bytes) {
+            return Base64.getEncoder().encodeToString(bytes)
+                    .replace('+', '-')
+                    .replace('=', '_')
+                    .replace('/', '~');
+        }
+    
+        static PrivateKey loadPrivateKey(String path) throws Exception {
+            byte[] keyBytes = Files.readAllBytes(new File(path).toPath());
+            return KeyFactory.getInstance("RSA")
+                    .generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
+        }
+    }
+    
+