garydgregory commented on code in PR #332:
URL: https://github.com/apache/commons-compress/pull/332#discussion_r1037737611


##########
src/main/java/org/apache/commons/compress/archivers/sevenz/AES256SHA256Decoder.java:
##########
@@ -126,4 +115,121 @@ public void close() throws IOException {
             }
         };
     }
+
+    @Override
+    OutputStream encode(OutputStream out, Object options) throws IOException {
+        AES256Options opts = (AES256Options) options;
+        final byte[] aesKeyBytes = sha256Password(opts.password, 
opts.numCyclesPower, opts.salt);
+        final SecretKey aesKey = new SecretKeySpec(aesKeyBytes, "AES");
+
+        final Cipher cipher;
+        try {
+            cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            cipher.init(Cipher.ENCRYPT_MODE, aesKey, new 
IvParameterSpec(opts.iv));
+        } catch (final GeneralSecurityException generalSecurityException) {
+            throw new IOException(
+                "Encryption error " + "(do you have the JCE Unlimited Strength 
Jurisdiction Policy Files installed?)",
+                generalSecurityException
+            );
+        }
+        return new OutputStream() {
+            final CipherOutputStream cipherOutputStream = new 
CipherOutputStream(out, cipher);
+
+            // Ensures that data are encrypt in respect of cipher block size 
and pad with '0' if smaller
+            // NOTE: As "AES/CBC/PKCS5Padding" is weak and should not be used, 
we use "AES/CBC/NoPadding" with this 
+            // manual implementation for padding possible thanks to the size 
of the file stored separately
+            final int cipherBlockSize = cipher.getBlockSize();
+            final byte[]  cipherBlockBuffer = new byte[cipherBlockSize];
+            private int count = 0;
+
+            @Override
+            public void write(int b) throws IOException {
+                cipherBlockBuffer[count++] = (byte) b;
+                if (count == cipherBlockSize) {
+                    flushBuffer();
+                } 
+            }
+
+            @Override
+            public void write(byte[] b, int off, int len) throws IOException {
+                int gap = len + count > cipherBlockSize ? cipherBlockSize - 
count : len;
+                System.arraycopy(b, off, cipherBlockBuffer, count, gap);
+                count += gap;
+
+                if (count == cipherBlockSize) {
+                    flushBuffer();
+
+                    if (len - gap >= cipherBlockSize) {
+                        // skip buffer to encrypt data chunks big enought to 
fit cipher block size
+                        int multipleCipherBlockSizeLen = (len - gap) / 
cipherBlockSize * cipherBlockSize;
+                        cipherOutputStream.write(b, off + gap, 
multipleCipherBlockSizeLen);
+                        gap += multipleCipherBlockSizeLen;
+                    }
+                    System.arraycopy(b, off + gap, cipherBlockBuffer, 0, len - 
gap);
+                    count = len - gap;
+                }
+            }
+
+            private void flushBuffer() throws IOException {
+                cipherOutputStream.write(cipherBlockBuffer);
+                count = 0;
+                Arrays.fill(cipherBlockBuffer, (byte) 0);
+            }
+
+            @Override
+            public void flush() throws IOException {
+                cipherOutputStream.flush();
+            }
+
+            @Override
+            public void close() throws IOException {
+                if (count > 0) {
+                    cipherOutputStream.write(cipherBlockBuffer);
+                }
+                cipherOutputStream.close();
+            }
+        };
+    }
+
+    private byte[] sha256Password(final byte[] password, final int 
numCyclesPower, final byte[] salt) throws IOException {
+        final MessageDigest digest;
+        try {
+            digest = MessageDigest.getInstance("SHA-256");
+        } catch (final NoSuchAlgorithmException noSuchAlgorithmException) {
+            throw new IOException("SHA-256 is unsupported by your Java 
implementation", noSuchAlgorithmException);

Review Comment:
   This is not possible since SHA-256 is required by the JRE specification, see 
https://docs.oracle.com/javase/8/docs/api/java/security/MessageDigest.html, 
therefore this could be an `IllegalStateException`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to