将Java Encrypion三倍化为Javascript解密
我正在使用Java对文本负载进行三重加密。首先,我创建一个临时密钥,用于加密有效负载:
private byte[] createEphemeralKey() throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("DESede");
keygen.init(168);
return keygen.generateKey().getEncoded();
}
然后我用所述密钥加密我的有效载荷:
private String encryptTripleDES(byte[] ephemeralKey, String payload) throws Exception {
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(ephemeralKey, "DESede"));
byte[] plainTextBytes = payload.getBytes();
byte[] cipherText = cipher.doFinal(plainTextBytes);
return Base64.getEncoder().encodeToString(cipherText);
}
还需要一个填充函数,以确保数据长度可被8整除:
private String adjustPadding(String input, int blockSize) {
int len = input.length() % blockSize;
int paddingLength = (len == 0) ? 0 : (blockSize - len);
while (paddingLength > 0) {
input += "F";
paddingLength--;
}
return input;
}
以下是我的过程:
String data = "Marnus"
byte[] = ephemeralKey = createEphemeralKey();
String adjustedData = adjustPadding (data,8);
String encryptedPayload = encryptTripleDES(ephemeralKey, adjustedData);
String encodedKey = Base64.getEncoder().encodeToString(ephemeralKey)
因此,我获取两个变量encryptedPayload
和encodedKey
,它们都是Base64编码的字符串,并通过HTTP将其发送到node express应用程序
在Javascript方面,我使用node-forge——以下是我的express应用程序中进行解密的部分:
let nodeBuffer = Buffer.from(data, 'base64')
let input = forge.util.createBuffer(nodeBuffer.toString('binary'))
// 3DES key and IV sizes
let keySize = 24;
let ivSize = 8;
let derivedBytes = forge.pbe.opensslDeriveBytes(ephemeralKey, null, keySize + ivSize);
let buffer = forge.util.createBuffer(derivedBytes);
let key = buffer.getBytes(keySize)
let iv = buffer.getBytes(ivSize)
let decipher = forge.cipher.createDecipher('3DES-ECB', key)
decipher.start({iv: iv})
decipher.update(input)
console.log('decipher result', decipher.finish())
let decryptedResult = decipher.output.data;
下面是node forge docs中的一个Triples DES示例:
一些注释: 我从一个常规缓冲区创建了一个node forge缓冲区,因为我没有示例中给出的输入文件。以下是文档中的说明,其中一个应该从另一个创建一个缓冲区:
*我使用base64,因为我在java端使用base64对发送的数据进行编码
然后,我没有盐,所以我把第二个参数null
留在了opensslDeriveBytes
中,这是我应该做的文档中指定的
第三,我也不确定我的24键大小是否正确
我的结果
因此,进行端到端测试会产生以下结果:
在我的Java应用程序中,测试数据是"Marnus"
,测试数据是encryptedPayload
,测试数据是ez+RweSAd+4=
,测试数据是encodedKey
然后在我的javascript代码中data
显然是ez+RweSAd+4=
(encryptedPayload),而ephemeralKey
是vCD9mBnWHPEBiQ0BGv7gc6GUCOoBgLCu
(encodedKey)
解密运行后,decryptedResult
的值是©ýÕ?µ{'
,这显然只是垃圾,因为它还没有编码,但我不知道该使用哪种编码
我试着使用forge.util.encode64(decipher.output.data)
,但那只是给了我qf3VP7UYeyc=
,这是不对的
不管它值多少钱here is the type那decipher.output
# 1 楼答案
通过更多的调整和测试不同的选项,我让它工作了——好消息是我设法让它与nodejs(v12.18.4)中的内置
crypto
库一起工作首先,JAVA端只需要更改密钥大小(从168更改为112),其余的保持不变——请参见下面的示例,作为一个方法(当然,为了可测试性和可用性,应该在最终实现中拆分):
在Javascript方面,我们保持简单: