【发布时间】:2014-03-24 13:25:52
【问题描述】:
我正在尝试使用 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();
}
现在按预期运行,文件“test-encrypted.txt”确实已加密,并且“test-decrypted.txt”==“test.txt”
然后我尝试使用 OpenSSL 在命令行上运行解密
openssl enc -d -aes-128-ecb -in test-encrypted.txt -k aes.key
然而,这总是给我
bad magic number
据我所知,Java 中使用的算法“AES”默认使用“ECB”模式,所以上面应该可以工作。我做错了什么。
【问题讨论】:
-
您的文件中可能有一些无法打印的 ascii 字符?尝试使用
-base64选项。 -
旁注:如果您想要 ECB 模式,请指定它。将
"AES"更改为"AES/ECB/<padding>"以避免歧义。 (其中<padding>是您首选的填充方案)。依赖默认值是不明智的做法。
标签: java encryption cryptography openssl