例 1:
私は最近、ある問題に悩んでいます。 Nodejs の AES 暗号化は、Java および C# の暗号化と矛盾します。もちろん、これを復号化することはできません。私は長い間苦労しました。ついにそれができなくなったので、ソースコードを確認しました。そうしないと、苦労し続けなければなりませんでした。ネット上では通常のnodejsのAES実装が他の言語と違うと言われています。そうですね〜〜たぶん。
nodejs の暗号モジュール。
var crypto = require('暗号') ;
var data = "156156165152165156156";
console.log('元の平文: ' data);
var アルゴリズム = 'aes-128-ecb';
var key = '78541561566';
var clearEncoding = 'utf8';
//var cipherEncoding = 'hex';
//次の行がコメントされていない場合、最終的な平文は間違っています。
var cipherEncoding = 'base64';
/*暗号化*/
var cipher = crypto.createCipher(アルゴリズム, キー);
var cipherChunks = [];
cipherChunks.push(cipher.update(data, clearEncoding, cipherEncoding));
cipherChunks.push(cipher.final(cipherEncoding));
console.log( cipherEncoding ' ciphertext: ' cipherChunks.join(''));
/*decryption*/
var decpher = crypto.createDecipher(algorithm, key);
var plainChunks = [];
(var i = 0;i < cipherChunks.length;i ) {
plainChunks.push(decpher.update(cipherChunks[i], cipherEncoding, clearEncoding));
}
plainChunks.push(decopher.final(clearEncoding));
console.log("UTF8 平文を解読しました: " plainChunks.join(''));
確かに、いいえ違いました~~暗号化と復号化は成功しました。ただし、Java や C# の暗号化とは異なります。神。皆さんもここで苦労していると思いますよね?実際、ベクトルを追加する限り、一貫性が保たれます。オンラインで見つかるリソースが少なすぎます。だからこそ、私は長い間苦労しました。
正しいコードは次のとおりです:
var crypto = require('crypto');
var data = "156156165152165156156";
console.log('元の平文: ' data);
var アルゴリズム = 'aes-128-ecb';
var key = '78541561566';
var clearEncoding = 'utf8';
var iv = "";
//var cipherEncoding = 'hex';
//次の行のコメントが解除されている場合、最終的な平文は間違っています。
var cipherEncoding = 'base64';
var cipher = crypto.createCipheriv(algorithm, key,iv);
var cipherChunks = [];
cipherChunks.push(cipher.update(data, clearEncoding, cipherEncoding));
cipherChunks.push(cipher.final(cipherEncoding));
console.log( cipherEncoding ' ciphertext: ' cipherChunks.join(''));
var decopher = crypto.createDecipheriv(algorithm, key,iv);
var plainChunks = [];
for (var i = 0;i plainChunks .push(decpher.update(cipherChunks[i], cipherEncoding, clearEncoding));
}
plainChunks.push(decopher.final(clearEncoding));
console.log("UTF8 平文が解読されました: " plainChunks.join(''));
比較により次のことが判明しました, 暗号化は一貫しています。さて、ノット~~~一日を無駄にしたあなたが大嫌いです。
例 2:
仕事中に、AES と Android クライアントの Java 復号化による nodejs 暗号化に遭遇しました。データをクエリした後、nodejs は Android クライアントによって暗号化されたコンテンツも復号化する必要があることに同意しました。 Java 側で MD5 で再度暗号化する必要があることがわかりました。以下は aes ecb 暗号化の内容です。cbc の場合は、秘密鍵 MD5 も暗号化する必要があります。
nodejs:
コードをコピー コードは次のとおりです:
/**
* aes 暗号化
* @param データ
* @param SecretKey
*/
encryptUtils.aesEncrypt = function(data, secretKey) {
var cipher = crypto.createCipher('aes-128-ecb',secretKey);
return cipher.update(data,'utf8','hex') cipher.final('hex');
}
/**
* aes 復号化
* @param データ
* @param SecretKey
* @returns {*}
*/
encryptUtils.aesDecrypt = function(data, SecretKey) {
var cipher = crypto.createDecipher('aes-128-ecb',秘密鍵);
return cipher.update(data,'hex','utf8') cipher.final('utf8');
}
java:
パッケージ com.iofamily.util;
java.security.MessageDigest をインポートします。
javax.crypto.Cipher をインポートします。
インポート javax.crypto.spec.SecretKeySpec;
/**
* Nodejs と一致する AES 暗号化
* @author lmiky
* @date 2014-2-25
*/
public class AESForNodejs {
public static Final String DEFAULT_CODING = "utf-8";
/**
* 解密
* @author lmiky
* @date 2014-2-25
* @param encrypted
* @param seed
* @return
* @throws Exception
*/
private static String decrypt(String encrypted, String seed) throws Exception {
byte[] keyb = seed.getBytes(DEFAULT_CODING);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(keyb);
SecretKeySpec skey = new SecretKeySpec(thedigest, "AES");
Cipher dcipher = Cipher.getInstance("AES");
dcipher.init(Cipher.DECRYPT_MODE, skey);
byte[] clearbyte = dcipher.doFinal(toByte(encrypted));
新しい文字列(クリアバイト)を返します。
}
/**
* 加密
* @author lmiky
* @date 2014-2-25
* @param content
* @param key
* @return
* @throws Exception
*/
public static String encrypt(String content, String key) throws Exception {
byte[] input = content.getBytes(DEFAULT_CODING);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(key.getBytes(DEFAULT_CODING));
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
暗号 cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength = cipher.doFinal(cipherText, ctLength);
return parseByte2HexStr(cipherText);
}
/**
* 文字列をバイト配列に変換
* @author lmiky
* @date 2014-2-25
* @param hexString
* @return
*/
private static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = 新しい byte[len];
for (int i = 0; i result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i 2), 16).byteValue() ;
}
結果を返します。
}
/**
* 16 進配列へのバイト
* @author lmiky
* @date 2014-2-25
* @param buf
* @return
*/
private static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' hex;
}
sb.append(hex);
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
System.out.println(AESForNodejs.encrypt("fsadfsdafsdafsdafsadfsadfsadf", "1234fghjnmlkiuhA"));
System.out.println(AESForNodejs.decrypt("5b8e85b7a86ad15a275a7cb61fe4c0606005e8741f68797718a3e90d74b5092a", "1234fghjnmlkiuhA"));
}
}