【发布时间】:2018-04-15 11:38:11
【问题描述】:
我想在 Java 中使用 AES/CFB/NoPadding 加密字节。
我在 Stackoverflow 上找到了以下问题,但它只涉及解密功能:AES Encryption in Golang and Decryption in Java
我将如何在 Java 中编写类似于以下 Go 代码的加密函数?
package main
import (
"io"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"crypto/rand"
)
func encrypt(key, data []byte) string {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
encoded := base64.StdEncoding.EncodeToString(data)
ciphertext := make( []byte, aes.BlockSize+len(encoded) )
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream( ciphertext[aes.BlockSize:], []byte(encoded) )
return ciphertext, nil
}
我的 Golang 解密函数是这样的(它应该返回 base64 代码):
func decrypt(key, data []byte) ([]byte, error) {
blockcipher, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(data) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
iv := data[:aes.BlockSize]
data = data[aes.BlockSize:]
cfb := cipher.NewCFBDecrypter(blockcipher, iv)
cfb.XORKeyStream(data, data)
return data, nil
}
我当前的 Java 加密代码(我似乎无法解密)如下所示:
private byte[] encrypt(byte[] payload) {
try {
SecretKeySpec key_spec = new SecretKeySpec(current_encryption_key, "AES");
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
byte[] encoded_payload = Base64.encode(payload, Base64.DEFAULT);
IvParameterSpec iv = new IvParameterSpec( new byte[16] );
cipher.init(Cipher.ENCRYPT_MODE, key_spec, iv);
return cipher.doFinal(encoded_payload);
} catch (Exception e) {
e.printStackTrace();
}
return new byte[0];
}
我的加密代码如下所示(在 Golang 和 Java 中都能正常工作):
private byte[] decrypt(byte[] payload) {
try {
SecretKeySpec key_spec = new SecretKeySpec(current_encryption_key, "AES");
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
int block_size = cipher.getBlockSize();
IvParameterSpec iv = new IvParameterSpec( Arrays.copyOf(payload, block_size) );
byte[] decryption_data = Arrays.copyOfRange(payload, block_size, payload.length);
cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
byte[] decrypted_payload = cipher.doFinal(decryption_data);
return Base64.decode(decrypted_payload, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
return new byte[0];
}
当我在 Java 中加密某些内容,然后尝试在 Java 中使用我的解密器时,我收到以下解密错误:
04-13 14:16:48.382 3791-3791/com.domain.interpretest W/System.err: java.lang.IllegalArgumentException: 16 > 9
04-13 14:16:48.388 3791-3791/com.domain.interpretest W/System.err: at java.util.Arrays.copyOfRange(Arrays.java:3447)
【问题讨论】:
-
特雷弗,请正确阅读我的问题。我不想要 CBC 加密,我想要 CFB 加密。我的问题也没有表明我想使用自己的 IV
-
Stackoverflow 不是代码翻译服务。密码是标准化的,你自己试试看,你为什么不呢?问题的一个提示:如果“CFB”在 Java 中不起作用,请尝试“CFB8”。祝你好运。
-
您好 Maarten,感谢您尝试回答我的问题。然而它没有用。我可以成功解密使用上述 Golang 代码加密的数据。我不知道你为什么告诉我这不是代码翻译服务,我认为添加我的代码示例是绝对详细地描述我的问题的最佳/唯一方式。
-
@MaartenBodewes 即使您只是评论简单的步骤(而不是代码)关于我应该如何在 Java 中使用 XORstream 创建 AES/CFB/NoPadding,我也会非常感激。