問題描述
尋找一種在節點中加密數據(主要是字符串)并在安卓應用程序(java)中解密的方法.
Looking for a way to encrypt data (mainly strings) in node and decrypt in an android app (java).
在每一個中都已成功完成(在節點中加密/解密,在 java 中加密/解密),但似乎無法在它們之間工作.
Have successfully done so in each one (encrypt/decrypt in node, and encrypt/decrypt in java) but can't seem to get it to work between them.
可能我沒有以相同的方式加密/解密,但是每種語言的每個庫對相同的事物都有不同的名稱...
Possibly I'm not encrypting/decrypting in the same way, but each library in each language has different names for same things...
任何幫助表示贊賞.
這里有一些代碼:Node.js
here's some code: Node.js
var crypto = require('crypto')
var cipher = crypto.createCipher('aes-128-cbc','somepass')
var text = "uncle had a little farm"
var crypted = cipher.update(text,'utf8','hex')
crypted += cipher.final('hex')
//now crypted contains the hex representation of the ciphertext
和java
private static String decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec );
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted);
}
原始密鑰是這樣創建的
private static byte[] getRawKey(String seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] seedBytes = seed.getBytes()
sr.setSeed(seedBytes);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
而加密的十六進制字符串被轉換成這樣的字節
while the encrypted hex string is converted to bytes like this
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
推薦答案
顯然,如果您將密碼傳遞給 crypto.createCipher()
它使用 OpenSSL 的 EVP_BytesToKey()
來導出密鑰.您可以傳遞一個原始字節緩沖區并使用它來初始化 Java 的 SecretKey
,或者在您的 Java 代碼中模擬 EVP_BytesToKey()
.使用 $ man EVP_BytesToKey
了解更多詳細信息,但本質上它使用 MD5 對密碼短語進行多次散列并連接一個鹽.
Apparently if you pass a passphrase to crypto.createCipher()
it uses OpenSSL's EVP_BytesToKey()
to derive the key. You can either pass a raw byte buffer and use the same to initialize Java's SecretKey
, or emulate EVP_BytesToKey()
in your Java code. Use $ man EVP_BytesToKey
for more details, but essentially it hashes the passphrase multiple times with MD5 and concatenates a salt.
至于使用原始密鑰,這樣的事情應該可以讓您使用原始密鑰:
As for using a raw key, something like this should let you use a raw key:
var c = crypto.createCipheriv("aes-128-ecb", new Buffer("00010203050607080a0b0c0d0f101112", "hex").toString("binary"), "");
請注意,由于您使用的是 CBC,因此您需要使用相同的 IV 進行加密和解密(您可能希望將其附加到您的消息等)
Note that since you are using CBC, you need to use the same IV for encryption and decryption (you might want to append it to your message, etc.)
強制警告:自己實施加密協議很少是一個好主意.即使你讓它工作,你會為所有消息使用相同的密鑰嗎?多長時間?如果您決定輪換密鑰,您將如何管理它.等等,等等.
Mandatory warning: implementing a crypto protocol yourself is rarely a good idea. Even if you get this to work, are you going to use the same key for all messages? For how long? If you decide to rotate the key, how to you manage this. Etc, .etc.
這篇關于使用 Node.js Crypto 模塊加密并使用 Java 解密(在 Android 應用程序中)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!