fix:兼容go版本的sm2

This commit is contained in:
ChessNineeee
2021-04-12 16:13:48 +08:00
parent bcd906e1a2
commit 74358fbc5e
7 changed files with 99 additions and 56 deletions
@@ -54,7 +54,14 @@ public class SM2PrivateKey implements PrivateKeyInterface {
@Override
public byte[] getBytes() {
return privateKey.getD().toByteArray();
byte[] bytes = privateKey.getD().toByteArray();
// 16进制表示法
StringBuilder sb = new StringBuilder();
for(int i=0;i < bytes.length;i++) {
sb.append(String.format("%02x", bytes[i]));
}
String hexStr = sb.toString();
return hexStr.getBytes();
}
@Override
@@ -71,11 +78,19 @@ public class SM2PrivateKey implements PrivateKeyInterface {
* @params d {byte[]}
* @return boolean
*/
// TODO 实现不同
public boolean setBytes(byte[] d){
// if (d.length != 64)
// return false;
String priStr = new String(d);
privateKey = new ECPrivateKeyParameters(new BigInteger(priStr, 16), SM2Base.DOMAIN_PARAMS);
if (d.length != 64 && d.length != 32 && d.length != 33)
return false;
switch (d.length){
case 32:
privateKey = new ECPrivateKeyParameters(new BigInteger(d), SM2Base.DOMAIN_PARAMS);
break;
case 64:
String priStr = new String(d);
privateKey = new ECPrivateKeyParameters(new BigInteger(priStr, 16), SM2Base.DOMAIN_PARAMS);
break;
}
return true;
}
@@ -46,6 +46,7 @@ public class SM2PublicKey implements PublicKeyInterface {
@Override
// TODO 实现不同
public byte[] getBytes() {
if(publicKey != null)
return publicKey.getQ().getEncoded(false); //不压缩
@@ -53,6 +54,7 @@ public class SM2PublicKey implements PublicKeyInterface {
}
@Override
// TODO 实现不同
public boolean setBytes(byte[] bytes) {
if(bytes.length != 65)
return false;
@@ -140,7 +140,7 @@ public class Identity {
}
/**
* 使用identity的钥对密文进行解密, 返回解密数据.
* 使用identity的钥对密文进行解密, 返回解密数据.
* identity中的私钥为空或密文有误时时将抛出异常
* @param cipher 密文
* @return byte[]
@@ -155,7 +155,7 @@ public class Identity {
return this.Prikey.decrypt(cipher);
}
/**
* 使用identity的钥对密文进行加密, 返回加密数据.
* 使用identity的钥对密文进行加密, 返回加密数据.
* identity中的公钥为空或原文有误时时将抛出异常
* @param content 原文
* @return byte[]
@@ -188,6 +188,7 @@ public class Identity {
byte[] bytesOfInnerIdentity = mapper.writeValueAsBytes(innerIdentity);
// logger.debug(ByteUtils.toHexString(bytesOfInnerIdentity));
if(passwd != null && passwd.length() != 0) {
// 关键函数
byte[] sm4key = KeyUtils.get16bytePasswd(passwd.getBytes());
byte[] cipher = SM4.encrypt_CBC_Padding(sm4key, new byte[16], bytesOfInnerIdentity);
return Base64.getEncoder().encode(cipher);
@@ -227,13 +228,16 @@ public class Identity {
return IdentityUtil.parseInnerToIdentity(innerIdentity);
}
// TODO: passwd ???
public boolean lock(String passwd, int algo) throws IdentityException {
public boolean lock(String passwd, int algo) throws IdentityException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidKeyException {
switch (algo){
case Common.SM4ECB:
if (passwd.length() != 16){
if (passwd.length() == 0){
throw new IdentityException("密码应为16位");
}
PrikeyRawByte = Prikey.getBytes();
byte[] passHash = KeyUtils.get16bytePasswd(passwd.getBytes());
byte[] by = Prikey.getBytes();
byte[] encMsg = SM4.encrypt_ECB_Padding(passHash, Prikey.getBytes());
PrikeyRawByte = encMsg;
Prikey = null;
return true;
default:
@@ -252,14 +256,10 @@ public class Identity {
if(passwd == null || passwd.length() == 0)
return false;
byte[] passHash = HashAlgo.sm3(passwd);
if (passHash.length == 32){
for (int i = 0; i < 16; i++){
passHash[i] += passHash[i+16];
}
}
byte[] dec = SM4.encrypt_ECB_NoPadding(Arrays.copyOfRange(passHash, 0, 16), PrikeyRawByte);
PrivateKeyInterface privateKey = KeyUtils.unMarshalPrivateKey(Arrays.copyOfRange(dec, 0, 64), KeyParam.PublicKeyAlgorithm);
byte[] passHash = KeyUtils.get16bytePasswd(passwd.getBytes());
// 解密后的私钥序列化数据
byte[] dec = SM4.decrypt_ECB_Padding(passHash, PrikeyRawByte);
PrivateKeyInterface privateKey = KeyUtils.unMarshalPrivateKey(dec, KeyParam.PublicKeyAlgorithm);
Prikey = privateKey;
PrikeyRawByte = null;
return true;
@@ -50,7 +50,8 @@ public class IdentityUtil {
innerIdentity.setPubkey(identity.getPubkey().getBytes());
innerIdentity.setPasswd(identity.getPasswd());
innerIdentity.setCert(CertUtils.toPem(identity.getCert(), identity.getPasswd().getBytes(), Common.SM4CBC));
// add
innerIdentity.setPrikeyRawByte(identity.getPrikeyRawByte());
return innerIdentity;
}
@@ -84,6 +85,7 @@ public class IdentityUtil {
Certificate certificate =
CertUtils.fromPem(innerIdentity.getCert(), innerIdentity.getPasswd().getBytes(), Common.SM4CBC);
identity.setCert(certificate);
identity.setPrikeyRawByte(innerIdentity.getPrikeyRawByte());
return identity;
}
@@ -1,5 +1,6 @@
package minsecurity.identity;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
/*
@@ -10,20 +11,29 @@ import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class InnerIdentity {
@JsonProperty("Name")
private String Name;
@JsonProperty("KeyParam")
private KeyParam KeyParam;
@JsonProperty("Prikey")
private byte[] Prikey;
@JsonProperty("Pubkey")
private byte[] Pubkey;
@JsonProperty("Passwd")
private String Passwd;
@JsonProperty("Cert")
private String Cert;
@JsonProperty("PrikeyRawByte")
private byte[] PrikeyRawByte;
public InnerIdentity(String name, minsecurity.identity.KeyParam keyParam, byte[] prikey, byte[] pubkey, String passwd, String cert) {
public InnerIdentity(String name, minsecurity.identity.KeyParam keyParam, byte[] prikey, byte[] pubkey, String passwd, String cert, byte[] prikeyRawByte) {
Name = name;
KeyParam = keyParam;
Prikey = prikey;
Pubkey = pubkey;
Passwd = passwd;
Cert = cert;
PrikeyRawByte = prikeyRawByte;
}
public InnerIdentity() {
@@ -87,8 +97,17 @@ public class InnerIdentity {
", Pubkey=" + (Pubkey == null ? "null" : ByteUtils.toHexString(Pubkey)) +
", Passwd='" + Passwd + '\'' +
", Cert='" + Cert + '\'' +
", PrikeyRawByte='" + PrikeyRawByte + '\''+
'}';
}
public byte[] getPrikeyRawByte() {
return PrikeyRawByte;
}
public void setPrikeyRawByte(byte[] prikeyRawByte) {
PrikeyRawByte = prikeyRawByte;
}
}
@@ -1,5 +1,7 @@
package minsecurity.identity;
import com.fasterxml.jackson.annotation.JsonProperty;
/*
* @Author: hongyu guo
* @Description:
@@ -8,7 +10,9 @@ package minsecurity.identity;
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class KeyParam {
@JsonProperty("PublicKeyAlgorithm")
public int PublicKeyAlgorithm;
@JsonProperty("SignatureAlgorithm")
public int SignatureAlgorithm;
public KeyParam(int publicKeyAlgorithm, int signatureAlgorithm) {
@@ -30,42 +30,42 @@ class OperationThread extends Thread{
System.out.println(String.format("Operation %d starting", this.threadNo));
try{
// 测试PersistIdentity
// SM2KeyPair pair = SM2KeyPair.generateKeyPair();
// Identity identity = new Identity();
// identity.setName("wzq"+this.threadNo);
// KeyParam keyParam = new KeyParam();
// keyParam.PublicKeyAlgorithm = 0;
// keyParam.SignatureAlgorithm = 0;
// identity.setKeyParam(keyParam);
// identity.setPrikey(pair.getSm2PrivateKey());
// identity.setPubkey(pair.getSm2PublicKey());
// identity.setPasswd("2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99");
// identity.lock("0123456789abcdef", Common.SM4ECB);
// Certificate cert = new Certificate();
// cert.setVersion(1);
// cert.setSerialNumber(1);
// cert.setPublicKey(pair.getSm2PublicKey());
// cert.setSignatureAlgorithm(Common.SM3withSM2); // TODO 名字有误? SM2withSM3?
// cert.setPublicKeyAlgorithm(Common.SM2);
// cert.setIssueTo("root");
// cert.setIssuer("root");
// long timestamp = System.currentTimeMillis() / 1000;
// cert.setTimestamp(timestamp); // 10bit timestamp
// cert.setNotAfter(timestamp); // 10bit timestamp
// cert.setNotBefore(timestamp + 1000); // 10bit timestamp
// cert.setKeyUsage(Common.CertSign);
// cert.setCA(true);
// CertUtils.signCert(cert, pair.getSm2PrivateKey());
//
// identity.setCert(cert);
// Db.persistIdentity(identity);
SM2KeyPair pair = SM2KeyPair.generateKeyPair();
Identity identity = new Identity();
identity.setName("wzq"+this.threadNo);
KeyParam keyParam = new KeyParam();
keyParam.PublicKeyAlgorithm = 0;
keyParam.SignatureAlgorithm = 0;
identity.setKeyParam(keyParam);
identity.setPrikey(pair.getSm2PrivateKey());
identity.setPubkey(pair.getSm2PublicKey());
identity.setPasswd("2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99");
identity.lock("0123456789abcdef", Common.SM4ECB);
Certificate cert = new Certificate();
cert.setVersion(1);
cert.setSerialNumber(1);
cert.setPublicKey(pair.getSm2PublicKey());
cert.setSignatureAlgorithm(Common.SM3withSM2); // TODO 名字有误? SM2withSM3?
cert.setPublicKeyAlgorithm(Common.SM2);
cert.setIssueTo("root");
cert.setIssuer("root");
long timestamp = System.currentTimeMillis() / 1000;
cert.setTimestamp(timestamp); // 10bit timestamp
cert.setNotAfter(timestamp); // 10bit timestamp
cert.setNotBefore(timestamp + 1000); // 10bit timestamp
cert.setKeyUsage(Common.CertSign);
cert.setCA(true);
CertUtils.signCert(cert, pair.getSm2PrivateKey());
// Identity id = Db.getIdentityByNameFromStorage("wzq"+this.threadNo);
//
// System.out.println("插入身份:" + id.getName());
// System.out.println(String.format("开始设置 wzq%d 为default 身份", this.threadNo));
//
// Db.SetDefaultIdentityByNameInStorage("wzq"+this.threadNo);
identity.setCert(cert);
Db.persistIdentity(identity);
Identity id = Db.getIdentityByNameFromStorage("wzq"+this.threadNo);
System.out.println("插入身份:" + id.getName());
System.out.println(String.format("开始设置 wzq%d 为default 身份", this.threadNo));
Db.SetDefaultIdentityByNameInStorage("wzq"+this.threadNo);
Identity id2 = Db.getDefaultIdentityFromStorage();
System.out.println("当前default身份:" + id2.getName());
@@ -100,7 +100,8 @@ public class DBTest {
System.out.println(identities.get(0).getPrikeyRawByte());
identities.get(0).unLock("0123456789abcdef", Common.SM4ECB);
PrivateKeyInterface id = identities.get(0).getPrikey();
System.out.println(identities.get(0).getPrikey().getBytes());
byte[] bytes = id.getBytes();
System.out.println(id.getBytes());
}catch (Exception ex){
System.out.println(ex.getMessage());
}