package com.joinsoft.util.sm2;
import com.joinsoft.WebConstants;
import org.apache.pdfbox.pdmodel.graphics.state.PDSoftMask;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import java.io.IOException;
import java.math.BigInteger;
public class SM2Util {
//生成随机秘钥对
public static SM2KeyPair generateKeyPair(){
SM2 sm2 = SM2.Instance();
AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();
ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();
ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();
BigInteger privateKey = ecpriv.getD();
ECPoint publicKey = ecpub.getQ();
System.out.println("公钥: " + Util.byteToHex(publicKey.getEncoded()));
System.out.println("私钥: " + Util.byteToHex(privateKey.toByteArray()));
return new SM2KeyPair(Util.byteToHex(publicKey.getEncoded(false)),Util.byteToHex(privateKey.toByteArray()));
}
//数据加密
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);
// System.out.println("C1 " + Util.byteToHex(c1.getEncoded()));
// System.out.println("C2 " + Util.byteToHex(source));
// System.out.println("C3 " + Util.byteToHex(c3));
//C1 C2 C3拼装成加密字串
return Util.byteToHex(c1.getEncoded(false)) + Util.byteToHex(source) + Util.byteToHex(c3);
}
//数据解密
public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException
{
if (privateKey == null || privateKey.length == 0)
{
return null;
}
if (encryptedData == null || encryptedData.length == 0)
{
return null;
}
//加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
String data = Util.byteToHex(encryptedData);
/***分解加密字串
* (C1 = C1标志位2位 + C1实体部分128位 = 130)
* (C3 = C3实体部分64位 = 64)
* (C2 = encryptedData.length * 2 - C1长度 - C2长度)
*/
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);
//通过C1实体字节来生成ECPoint
ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
Cipher cipher = new Cipher();
cipher.Init_dec(userD, c1);
cipher.Decrypt(c2);
cipher.Dofinal(c3);
//返回解密结果
return c2;
}
public static void main(String[] args) throws IOException {
// SM2Util.generateKeyPair();
String plainText = "Hello SM2 !";
byte[] sourceData = plainText.getBytes();
String decryptname = SM2Util.encrypt(Util.hexToByte(WebConstants.publick_SM2kh), sourceData);
byte[] decryptname1 = SM2Util.decrypt(Util.hexToByte(WebConstants.PRIVATEKEY_SM2kh), Util.hexToByte(decryptname));
plainText=new String(decryptname1,"utf-8");
System.out.println(plainText);
}
}
国密算法sm2、sm3
最新推荐文章于 2024-04-11 07:03:16 发布