您好我正在使用openSSL命令来加密和解密我的消息。现在我希望在java代码中转换此命令,我已经尝试了在Web上提供的不同解决方案,但没有任何代码与结果匹配。
这是我的OpenSSL命令,其中包含我在评论中的不足之处:
key="FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA"
# Getting 16 digits from the iv.txt file and putting it into the bin
head -c 16 iv.txt > iv.bin
# Converting iv.bin text into the HEXA value
iv=`xxd -l 16 -p iv.bin`
# encrypt without "-a"
openssl enc -aes-256-cbc -K $key -iv $iv -in plainKey.txt -out encryptedKey.bin
# printing encrypted results in base64 format this need to be matched with my java code.
echo "<enc>"`cat encryptedKey.bin | base64`"</enc>"
这就是我在Java中所做的:
注意:这个代码来自堆栈溢出,接受了一些微小的改动,我也尝试了其他一些代码,但是这里不能全部提及。
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class Test {
public static void main(String[] args) {
try {
runEncryption();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void runEncryption() throws Exception
{
//String to be encrypted
String plainText = "abcd@1234\n";
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// IV text
String iv = "C837E1B6C3D3A7E28F47719DE0C182C9";
// getting 16 characters of iv text
iv = iv.substring(0,16);
// Value of key
String key = "FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA";
// Logic for converting 16 Digits of IV into HEX
StringBuffer hexString = new StringBuffer();
for (int i=0;i<iv.getBytes().length;i++) {
String hex=Integer.toHexString(0xff & iv.getBytes()[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
// Seems something wrong here because if i am passing all the bytes to keySpe like key.getBytes() it is producing exception so i am passing 16 bytes as previous code was doing in SO
SecretKeySpec keySpec = new SecretKeySpec(hexToBytes(key), 0, 16, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString()));
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
String encryptedBase64 = new String(DatatypeConverter.printBase64Binary(encrypted));
System.out.println("");
System.out.println("Encrypted base64 = " + encryptedBase64);
}
private static byte[] hexToBytes(String s)
{
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2)
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
return data;
}
}
我使用openSSL命令生成密钥和iv
openssl enc -aes-256-cbc -k secret -P -md sha1
它看起来有点不对劲,因为如果我将所有字节传递给keySpec,就像key.getBytes()那样产生异常,所以我传递了16个字节,因为之前的代码在SO中做了我也在代码注释中提到了这个请告知此感谢。
答案 0 :(得分:0)
您的代码中有几处错误
让我们假设您想要做的是
openssl enc -aes-256-cbc -K FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA -iv 03B13BBE886F00E00000000000000000 -base64 -in input.txt
在你的代码中你有一些错误(wtf时刻)。我不会为你解决这些问题,但基本上是:
我建议使用一些普通的库(例如commons-codec,..)从十六进制编码/解码,虽然它似乎已经工作到目前为止
您正在使用16字节(128位)iv和密钥有效地执行AES-128。您需要使用具有密钥和长度为256位(32字节)的AES-256。您已将两者都切成16个字节,因此它们与openssl使用的值不同
主要突破点:IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString()));
请稍微考虑一下。 hexToBytes(iv)