我必须在 NodeJS 中实现 RC4 密码,代码如下:
function cipher (CRYPTO, str) {
const cipher = crypto.createCipher(CRYPTO.cipherAlgorithm, CRYPTO.password);
return Buffer.concat([
cipher.update(str, 'utf-8'),
cipher.final()
]).toString(CRYPTO.encoding);
}
const CRYPTO = {
cipherAlgorithm: 'rc4',
password: 'trololol',
encoding: 'base64'
};
cipher(CRYPTO, '0612345678');
// returns 'yTXp/PZzn+wYsQ=='
当我使用 open ssl 检查我的实现时,我得到了相同的结果:
echo -ne "0612345678" | openssl rc4 -pass "pass:trololol" -e -nosalt | base64
> yTXp/PZzn+wYsQ==
但通过我们的合作伙伴实现,结果确实不同。它是用 Java 编写的,所以我尝试做一个,结果与他相同:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class Encryptor {
private static String algorithm = "RC4";
public static String encrypt(String key, String value) {
try {
SecretKeySpec rc4Key = new SecretKeySpec(key.getBytes(), algorithm);
Cipher rc4 = Cipher.getInstance(algorithm);
rc4.init(Cipher.ENCRYPT_MODE, rc4Key);
byte [] encrypted = rc4.update(value.getBytes());
return DatatypeConverter.printBase64Binary(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key = "trololol";
String value = "0612345678";
System.out.println(encrypt(key, value));
}
}
运行上面的命令会给出:
javac Encryptor.java && java Encryptor
> LYlbWr0URiz+wA==
Java 中的 RC4 算法是否可能与其他算法不同,或者 Java 实现中存在问题?
最佳答案
区别在于“密码”与“ key ”。
例如,对于 Node 和 OpenSSL,“密码”意味着要散列的某个值 ( using MD5 ),以生成用于加密/解密的 key 。
如果您使用“密码”值作为键(使用空 IV),您将匹配从 Java 接收的值。以 Node 为例,更改为 createCipheriv()
函数:
crypto.createCipheriv(CRYPTO.cipherAlgorithm, CRYPTO.password, Buffer.alloc(0));
关于java - RC4 实现之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40424606/