您好我已经使用相同的算法编写了nodejs加密和Java加密。但是Java和NodeJS正在返回不同的加密字符串。请帮帮我。
//这是我的Java代码
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public enum AESUtil {
;
private static final String ENCRYPTION_KEY = "RwcmlVpg";
private static final String ENCRYPTION_IV = "4e5Wa71fYoT7MFEX";
public static String encrypt(String src) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, makeKey(), makeIv());
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(cipher.doFinal(src.getBytes()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String decrypt(String src) {
String decrypted = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv());
Base64.Decoder decoder = Base64.getDecoder();
decrypted = new String(cipher.doFinal(decoder.decode(src)));
} catch (Exception e) {
throw new RuntimeException(e);
}
return decrypted;
}
static AlgorithmParameterSpec makeIv() {
try {
return new IvParameterSpec(ENCRYPTION_IV.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
static Key makeKey() {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] key = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
return new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
//下面是测试上面代码的代码
public class AESMain {
/**
* @param args
*/
public static void main(String[] args) {
String src = "Hello,CryptWorld";
String encrypted = AESUtil.encrypt(src);
String decrypted = AESUtil.decrypt(encrypted);
System.out.println("src: " + src);
System.out.println("encrypted: " + encrypted);
System.out.println("decrypted: " + decrypted);
}
}
以上代码的回复是
src: Hello,CryptWorld
encrypted: rh7ro9NH1XZeLX95paLETDgYxRbnDoOIrxarO0Sy73s=
decrypted: Hello,CryptWorld
//节点JS代码
var Encrypt, crypto;
crypto = require("crypto");
Encrypt = module.exports = (function() {
var b64dec, b64enc, cipher, decrypt, encrypt, iv, key;
key = crypto.createHash("sha256").update("RwcmlVpg").digest();
iv = '4e5Wa71fYoT7MFEX';
cipher = function(mode, data) {
var encipher, encoded;
encipher = crypto[mode]("aes-256-cbc", key, iv);
encoded = encipher.update(data);
encoded += encipher.final();
return encoded;
};
encrypt = function(data) {
return b64enc(cipher("createCipheriv", data));
};
decrypt = function(data) {
return cipher("createDecipheriv", b64dec(data));
};
b64enc = function(data) {
var b;
b = new Buffer(data, "binary");
return b.toString("base64");
};
b64dec = function(data) {
var b;
b = new Buffer(data, "base64");
return b.toString("binary");
};
return {
encrypt: encrypt,
decrypt: decrypt
};
})();
var expected = Encrypt.encrypt("Hello,CryptWorld");
console.log("expected " + expected);
来自Node JS的响应是
expected /R79/f1H/XZeLX95/f39TDgY/Rb9Dv39/Rb9O0T9/Xs=
节点js版本为v6.10.1,JDK版本为1.8.0_77。
我真的不知道我错过了什么。
答案 0 :(得分:0)
我的第一个提示是确保你完全相同:
在两个程序中,用于加密的文本和密钥。尝试将文本缓冲区和密钥打印为十六进制,并在进行任何加密之前对其进行比较。如果他们不同,那么你的问题就出现了。如果它们相同,则加密本身可能存在问题。
请注意,默认情况下,Node使用UTF-8,而Java据我所知在内部使用UCS-2。我看到你正在尝试转换编码,但是在加密步骤之前仔细检查密钥和明文的环境中的结果。
另外,请确保您不加密字符串的base64表示而不是字符串本身,或者如果您使用base64作为密钥,那么您可以一致地执行此操作。
此外,在加密前打印两个密钥。您以编程方式构建它们,以确保您知道它们最终是什么。
如果你确保你有相同的密钥,相同的消息,相同的编码,行结尾和表示(hex,base64等),那么使用一些在线工具进行AES加密,如:
并比较你的哪个程序正确完成工作。
答案 1 :(得分:0)
我不是javascript或node.js专家,但我认为问题是cipher.final()
和Buffer
正在返回Buffer.concat(...)
的实例,而不是字符串。因此,您必须使用cipher = function (mode, data) {
var encipher, encoded;
encipher = crypto[mode]("aes-256-cbc", key, iv);
cipher1 = encipher.update(data);
cipher2 = encipher.final();
return Buffer.concat([cipher1, cipher2]);
};
来连接它们,即
Shader "TFTM/Skybox2CubeBlend" {
Properties {
_Blend ("Blend", Range (0, 1) ) = 0.0
_Rotation ("Rotation", Range(0, 360)) = 0
_Tex ("Cubemap (HDR)", Cube) = "grey" {}
_OverlayTex ("CubemapOverlay (HDR)", Cube) = "grey" {}
}
SubShader {
Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
Cull Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
samplerCUBE _Tex;
samplerCUBE _OverlayTex;
half4 _Tex_HDR;
half4 _Tint;
half _Exposure;
float _Rotation;
float _Blend;
float3 RotateAroundYInDegrees (float3 vertex, float degrees)
{
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, -sina, sina, cosa);
return float3(mul(m, vertex.xz), vertex.y).xzy;
}
struct appdata_t {
float4 vertex : POSITION;
};
struct v2f {
float4 vertex : SV_POSITION;
float3 texcoord : TEXCOORD0;
};
v2f vert (appdata_t v)
{
v2f o;
float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
o.vertex = UnityObjectToClipPos(rotated);
o.texcoord = v.vertex.xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half4 tex = texCUBE (_Tex, i.texcoord);
half4 tex2 = texCUBE (_OverlayTex, i.texcoord);
float4 env = lerp( tex, tex2, _Blend );
half3 c = DecodeHDR (env, _Tex_HDR);
return half4(c, 1);
}
ENDCG
}
}
Fallback Off
}
此外,在任何努力实现可移植性或互操作性的代码中,绝不应该使用此regular expression方法或此String.getBytes()
构造函数。相反,请始终明确指定charset。我会推荐UTF_8,例如所以请使用String(byte[])
和String.getBytes(StandardCharsets.UTF_8)
。