目录
- SM2加解密
- SM3加密
- js
- java
- sm3前后台(js/java)加密不一致原因
- SM4加解密
之前做一个项目的时候需要用到国密SM2,SM3,SM4的加解密方法,网上搜到的方法存在一些问题,例如sm2的前台解密方法没有找到,sm3相同参数前后台加密不一致等。写个文章记录总结一下,给后来的朋友提供一点帮助。
SM2加解密
js
function encodepwdSM2(username){
var pubkeyHex ="*********";
var msgData =CryptoJS.enc.Utf8.parse(username);
if (pubkeyHex.length > 130) {
pubkeyHex = pubkeyHex.substr(pubkeyHex.length - 130);
}
var cipherMode = "0";
var cipher = new SM2Cipher(cipherMode);
var userKey = cipher.CreatePoint(pubkeyHex);
msgData = cipher.str2Bytes(msgData.toString());
var encryptData = cipher.Encrypt(userKey, msgData);
return encryptData;
}
function decodepwdSM2(username){
var privateKey = "**************";
var msgData =CryptoJS.enc.Utf8.parse(username);
if (privateKey.length > 130) {
privateKey = privateKey.substr(privateKey.length - 130);
}
var cipherMode = "0";
var cipher = new SM2Cipher(cipherMode);
var userKey = new BigInteger(privateKey, 16);
msgData = username;
var decryptData = cipher.Decrypt(userKey, msgData);
return decryptData;
}
java
public static String encrypt(byte[] publicKey, byte[] data)
throws IOException
{
if ((publicKey == null) || (publicKey.length == 0))
{
return null;
}
if ((data == null) || (data.length == 0))
{
return null;
}
byte[] source = new byte[data.length];
System.arraycopy(data, 0, source, 0, data.length);
Cipher cipher = new Cipher();
SM2 sm2 = SM2.Instance();
ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);
ECPoint c1 = cipher.Init_enc(sm2, userKey);
cipher.Encrypt(source);
byte[] c3 = new byte[32];
cipher.Dofinal(c3);
return Util.byteToHex(c1.getEncoded()) + Util.byteToHex(source) + Util.byteToHex(c3);
}
public static String decrypt(String pk, String encryptedDataParam)
throws IOException
{
if ((pk == null) || (pk.length() == 0))
{
return null;
}
if ((encryptedDataParam == null) || (encryptedDataParam.length() == 0))
{
return null;
}
byte[] privateKey = Util.hexToByte(pk);
byte[] encryptedData = Util.hexToByte(encryptedDataParam);
String data = Util.byteToHex(encryptedData);
byte[] c1Bytes = Util.hexToByte(data.substring(0, 130));
int c2Len = encryptedData.length - 97;
byte[] c2 = Util.hexToByte(data.substring(130, 130 + 2 * c2Len));
byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len, 194 + 2 * c2Len));
SM2 sm2 = SM2.Instance();
BigInteger userD = new BigInteger(1, privateKey);
ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
Cipher cipher = new Cipher();
cipher.Init_dec(userD, c1);
cipher.Decrypt(c2);
cipher.Dofinal(c3);
return new String(c2);
}
SM3加密
js
function encodepwdSM3(msg){
var msgData = CryptoJS.enc.Utf8.parse(msg);
var sm3keycur = new SM3Digest();
msgData = sm3keycur.GetWords(msgData.toString());
sm3keycur.BlockUpdate(msgData, 0, msgData.length);
var c3 = new Array(32);
sm3keycur.DoFinal(c3, 0);
for(var i = 0,len = c3.length; i < len; i++){
if(256 == c3[i]){
c3[i]=0;
}
}
var hashHex = sm3keycur.GetHex(c3).toString();
return hashHex;
}
java
import org.bouncycastle.util.encoders.Hex;
public class SM3Utils
{
public String encrypt(String msg)
{
byte[] md3 = new byte[32];
byte[] msg3 = msg.getBytes();
SM3Digest sm3 = new SM3Digest();
sm3.update(msg3, 0, msg3.length);
sm3.doFinal(md3, 0);
String s3 = new String(Hex.encode(md3));
return s3;
}
}
sm3前后台(js/java)加密不一致原因
经过比对加密过程每一步的数据,发现加密完之后获得的byte[]不一致,后台数组中每个元素在[-128,127]之间,前台在[1,256]之间,相当前台于将后台的负数通过+256的形式转换为正数,但把0也转换成了256,导致讲byte[]转换为String格式之后不一致,只需要将前台byte[]中的256替换回0即可。
SM4加解密
js
function encodepwdSM4(username){
var type=typeof(username);
if(type=="number"){
username=username+"";
}
var sm4 = new SM4Util();
var encryptData=sm4.encryptData_ECB(username);
return encryptData;
}
function decodepwd(username){
var sm4 = new SM4Util();
var encryptData=sm4.decryptData_ECB(username);;
return encryptData;
}
java
public String encryptData_ECB(String plainText)
{
try
{
SM4_Context ctx = new SM4_Context();
ctx.isPadding = true;
ctx.mode = SM4.SM4_ENCRYPT;
byte[] keyBytes;
keyBytes = aqzj.getBytes();
SM4 sm4 = new SM4();
sm4.sm4_setkey_enc(ctx, keyBytes);
byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8"));
String cipherText = new BASE64Encoder().encode(encrypted);
if (cipherText != null && cipherText.trim().length() > 0)
{
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(cipherText);
cipherText = m.replaceAll("");
}
return cipherText;
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
public String decryptData_ECB(String cipherText)
{
try
{
SM4_Context ctx = new SM4_Context();
ctx.isPadding = true;
ctx.mode = SM4.SM4_DECRYPT;
byte[] keyBytes;
keyBytes = aqzj.getBytes();
SM4 sm4 = new SM4();
sm4.sm4_setkey_dec(ctx, keyBytes);
byte[] decrypted = sm4.sm4_crypt_ecb(ctx, new BASE64Decoder().decodeBuffer(cipherText));
return new String(decrypted, "UTF-8");
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}