AES - 用 Ja​​va 简单加密,用 openssl 解密

kab*_*bal 5 java encryption openssl cryptography

我正在尝试使用 Java Cryto 在 Java 中进行简单的 AES 加密,然后可以使用 OpenSSL 在 ObjectiveC 中对其进行解密。

因为我不是在做 ObjectiveC 方面的工作,所以我想确保它可以工作,使用 openSSL 命令行,但我总是得到“坏幻数”

这是我的 Java 代码

public class EncryptionUtils {

private static final String AES_CIPHER_METHOD = "AES";
private static final int AES_KEY_SIZE = 128;

public static byte[] generateAesKey() throws NoSuchAlgorithmException {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_CIPHER_METHOD);
    keyGenerator.init(AES_KEY_SIZE);
    SecretKey key = keyGenerator.generateKey();
    return key.getEncoded();
}

public static SecretKeySpec createAesKeySpec(byte[] aesKey) {
    return new SecretKeySpec(aesKey, AES_CIPHER_METHOD);
}

public static void aesEncryptFile(File in, File out, SecretKeySpec aesKeySpec) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
    Cipher aesCipher = Cipher.getInstance(AES_CIPHER_METHOD);
    aesCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec);
    InputStream inputStream = new FileInputStream(in);
    try {
        OutputStream outputStream = new CipherOutputStream(new FileOutputStream(out), aesCipher);
        try {
            IOUtils.copy(inputStream , outputStream);
        } finally {
            outputStream.close();
        }
    } finally {
        inputStream.close();
    }
}
}


//testcode
@Test
public void testAesEncryptFile() throws IOException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
    byte[] aesKey = EncryptionUtils.generateAesKey();
    SecretKeySpec aesKeySpec = EncryptionUtils.createAesKeySpec(aesKey);
    EncryptionUtils.aesEncryptFile(new File("C:\\test\\test.txt"), new File("C:\\test\\test-encrypted.txt"), aesKeySpec);

    FileOutputStream outputStream = new FileOutputStream("C:\\test\\aes.key");
    outputStream.write(aesKey);
    outputStream.close();
}

@Test
public void testAesDecryptFile() throws IOException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
    FileInputStream keyFis = new FileInputStream("C:\\test\\aes.key");
    ByteArrayOutputStream keyBaos = new ByteArrayOutputStream();
    IOUtils.copy(keyFis, keyBaos);

    SecretKeySpec keySpec = new SecretKeySpec(keyBaos.toByteArray(), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, keySpec);

    FileInputStream fileInputStream = new FileInputStream("C:\\test\\test-encrypted.txt");
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    IOUtils.copy(fileInputStream, baos);

    byte[] decrypted = cipher.doFinal(baos.toByteArray());
    FileOutputStream outputStream = new FileOutputStream("C:\\test\\test-decrypted.txt");
    outputStream.write(decrypted);
    outputStream.close();

}
Run Code Online (Sandbox Code Playgroud)

现在按预期运行,文件“test-encrypted.txt”确实已加密,并且“test-decrypted.txt”==“test.txt”

然后我尝试使用 OpenSSL 在命令行上运行解密

openssl enc -d -aes-128-ecb -in test-encrypted.txt -k aes.key
Run Code Online (Sandbox Code Playgroud)

然而,这总是给我

bad magic number
Run Code Online (Sandbox Code Playgroud)

从我所见,Java中的使用算法“AES”默认使用“ECB”模式,所以上面的应该可以工作。我究竟做错了什么。

Maa*_*wes 0

问题出在钥匙上。该-k参数需要一个密码,而不是一个文件。反过来,当 openssl 加密例程使用密码时,会在加密结果前面添加一个 magic 和 salt。这就是找不到的魔法。

要使用 openssl 命令行,请打印出十六进制密钥并使用该-K选项而不是小写选项-k

您还可以使用:

`cat aes.key`
Run Code Online (Sandbox Code Playgroud)

作为 after 的参数-K,假设 aes.key 包含十六进制的密钥。