mirror of
https://gitee.com/willfree/min-dev-java.git
synced 2026-06-17 18:20:25 +08:00
VMS的注册登录接口测试通过(原有问题是在签名之后默认加了一层base64编码,去掉之后,server即可验签通过);尚存问题是:证书的导入导出
This commit is contained in:
@@ -12,11 +12,11 @@ import VMSConnection.TCPNet.Message.BaseStruct;
|
||||
public class LoginRequest extends BaseStruct {
|
||||
public String Name;
|
||||
public String Password;
|
||||
public String Certification;
|
||||
public String Certificate;
|
||||
|
||||
public LoginRequest(String name, String password, String certification) {
|
||||
Name = name;
|
||||
Password = password;
|
||||
Certification = certification;
|
||||
Certificate = certification;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ import VMSConnection.TCPNet.Message.BaseStruct;
|
||||
public class LoginWithSignRequest extends BaseStruct {
|
||||
public String Name;
|
||||
public String Password;
|
||||
public String Certification;
|
||||
public String Certificate;
|
||||
public byte[] Signature;
|
||||
|
||||
public LoginWithSignRequest(String name, String password, String certification, byte[] signature) {
|
||||
Name = name;
|
||||
Password = password;
|
||||
Certification = certification;
|
||||
Certificate = certification;
|
||||
Signature = signature;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class RegisterRequest extends BaseStruct {
|
||||
public String Invitation;
|
||||
public String Email;
|
||||
public String DeviceInfo;
|
||||
public String Certification;
|
||||
public String Certificate;
|
||||
public int IsRevoked;
|
||||
public int UGroupID;
|
||||
public String TimeStamp;
|
||||
@@ -33,7 +33,7 @@ public class RegisterRequest extends BaseStruct {
|
||||
Invitation = invitation;
|
||||
Email = email;
|
||||
DeviceInfo = deviceInfo;
|
||||
Certification = certification;
|
||||
Certificate = certification;
|
||||
IsRevoked = isRevoked;
|
||||
this.UGroupID = UGroupID;
|
||||
TimeStamp = timeStamp;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class RegisterWithSignRequest extends BaseStruct {
|
||||
public String Invitation;
|
||||
public String Email;
|
||||
public String DeviceInfo;
|
||||
public String Certification;
|
||||
public String Certificate;
|
||||
public String Pubkey;
|
||||
public int IsRevoked;
|
||||
public int UGroupID;
|
||||
@@ -35,7 +35,7 @@ public class RegisterWithSignRequest extends BaseStruct {
|
||||
Invitation = invitation;
|
||||
Email = email;
|
||||
DeviceInfo = deviceInfo;
|
||||
Certification = certification;
|
||||
Certificate = certification;
|
||||
this.Pubkey=pubkey;
|
||||
IsRevoked = isRevoked;
|
||||
this.UGroupID = UGroupID;
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -107,6 +108,17 @@ public class BC_KeyManager {
|
||||
return Base64Helper.BlockChain_Base64Encode(sig);
|
||||
}
|
||||
|
||||
public byte[] SignRaw(byte[] text) throws CryptoException {
|
||||
byte[] sig=this.prk.sign(text);
|
||||
System.out.println("sign raw: "+new String(sig));
|
||||
return sig;
|
||||
}
|
||||
|
||||
public BigInteger[] SignNRS(byte[] text) throws CryptoException {
|
||||
BigInteger[] sig=this.prk.signNRS(text);
|
||||
return (sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥验签
|
||||
* @param text
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package VMSConnection.Security.SM2;
|
||||
|
||||
import minsecurity.crypto.sm2.SM2Signer_New;
|
||||
import org.bouncycastle.crypto.CipherParameters;
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
@@ -107,5 +108,15 @@ public class SM2PrivateKey implements PrivateKeyInterface {
|
||||
return signer.generateSignature();
|
||||
}
|
||||
|
||||
public BigInteger[] signNRS(byte[] content) throws CryptoException {
|
||||
SM2Signer_New signer = new SM2Signer_New();
|
||||
CipherParameters param = null;
|
||||
ParametersWithRandom pwr = new ParametersWithRandom(privateKey, new SecureRandom());
|
||||
param = pwr;
|
||||
signer.init(true, param);
|
||||
signer.update(content, 0, content.length);
|
||||
return signer.generateSignatureNRS();
|
||||
}
|
||||
|
||||
private ECPrivateKeyParameters privateKey;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,17 @@ public enum KeyManagerExample {
|
||||
.getCert();
|
||||
}
|
||||
|
||||
public Identity getIdentity(String identityName,String appKeyPath){
|
||||
return KeyManagerExample.INSTANCE.initKeyChain(identityName,appKeyPath)
|
||||
.getKeyChain()
|
||||
.getCurrentIdentity();
|
||||
}
|
||||
|
||||
public KeyChain getKeyChain(String identityName,String appKeyPath){
|
||||
return KeyManagerExample.INSTANCE.initKeyChain(identityName,appKeyPath)
|
||||
.getKeyChain();
|
||||
}
|
||||
|
||||
// 判断本地是否有某个标识名对应的证书
|
||||
public boolean isInKeyChain(String identityName,String appKeyPath) {
|
||||
KeyChain keyChain = null;
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package examples;
|
||||
|
||||
import VMSConnection.Security.BC_KeyManager;
|
||||
import VMSConnection.Utils.Base64Helper;
|
||||
import minsecurity.certificate.cert.CertException;
|
||||
import minsecurity.certificate.cert.Certificate;
|
||||
import minsecurity.crypto.AsymKeyException;
|
||||
import minsecurity.identity.Identity;
|
||||
import minsecurity.identity.IdentityException;
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
import security.KeyChain;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* @Author: Wang Feng
|
||||
* @Description: VPN登录DEMO
|
||||
* 主要依赖于VMSConnection模块
|
||||
* @Version: 1.0.0
|
||||
* @Date: 21:48 2021/7/12
|
||||
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
||||
*/
|
||||
public class VPNLoginExample {
|
||||
public String username="wefree";
|
||||
|
||||
// 生成本地密钥,持久化存储那种
|
||||
private void generateForeverIdentity(){
|
||||
KeyManagerExample.INSTANCE.initKeyChain("/"+username,"D:\\TEST\\Identitys\\");
|
||||
}
|
||||
|
||||
// 导出证书
|
||||
|
||||
public static void main(String[] args){
|
||||
// 生成密钥
|
||||
VPNLoginExample vpnExample=new VPNLoginExample();
|
||||
vpnExample.generateForeverIdentity();
|
||||
// 已有证书
|
||||
String oldCert="BtCN510lqxedaQkQ7PR/jBGdMFO933mMpI4Px9kD24lxyVxJ1xiEGM7" +
|
||||
"ZgGqGHcl+GqZNZP6cCk4a6sPy34qIsaZd40O33/O6o6jHiLTnhhgG4/8R47Vz" +
|
||||
"3lBk26JOomTz+PXFgzlA7qxsBBsBE1CeqjaMUDsOg8jLlFnKQq+04rF9lvMFQPt" +
|
||||
"PHn1uhwJ5RVdv8fDOTqZk0IDTG9biWESVlebskLv8zfxbglxmjcSoicmUtyOrcbIq" +
|
||||
"gNDbSEIcLZCxW/e0szJAWlJQ3HnFtBrZ0UWfvBUuVAvb0oEF/9klX+x6IecNl5sdwt" +
|
||||
"/Ax3vBdUhfQmgliizCnVEseY1HMmVoFrKVNjKPhwqqUwiA1GUdOUjfReRoovRCgvia6V" +
|
||||
"NVdndbJo1QAIKeULC4q4kf7mConm9CQisoVfVqiBr4Q6cZh6wFzqPBk1xN2X3XSYaOuD8g" +
|
||||
"I+mPdroRElokTeq52/REMYWQGQVWMlh7p6hu0krSOXx32zqzvezr2okiI5WJloyUSsKsIWI" +
|
||||
"n5lns1p1K38w5zOs+hZuJC2BBGI+nwwYeWEgFNKZODmMPiRNlHA12YhzaH0WEkY8vtYZvh" +
|
||||
"ttVpTkGI3n7bYLq2iFeeI/0Xf64KmMBFDPxboMQ4uku5q2vSqPxJ9wBfgSpbctbAXxBv9ZGZJowFYfM" +
|
||||
"V73Yi1QGmjo8e6+heOuAIhFxDzTwub0bzrrFf3MTabvPg1kDIl0+PgzyK8tkpciY" +
|
||||
"NPTtqt1V1g0p2zUtuNySV8Hv7wixtlM54ruI";
|
||||
// 使用
|
||||
try {
|
||||
String cert=KeyManagerExample.INSTANCE.getKeyChain().getIdentifyManager()
|
||||
.dumpCert("/username");
|
||||
System.out.println("cert: "+cert);
|
||||
String pubkey=new String(KeyManagerExample.INSTANCE.getKeyChain()
|
||||
.getCurrentIdentity().getPubkey().getBytes());
|
||||
System.out.println("pubkey: "+pubkey);
|
||||
byte[] sig;
|
||||
try {
|
||||
sig=KeyManagerExample.INSTANCE.getKeyChain()
|
||||
.getCurrentIdentity().sign("wefree".getBytes(StandardCharsets.UTF_8));
|
||||
} catch (CryptoException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
// sig用base64编码一次
|
||||
sig= Base64Helper.BlockChain_Base64Encode(sig).getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
BC_KeyManager bc=new BC_KeyManager();
|
||||
bc.SetPubkey(pubkey);
|
||||
boolean res=bc.Verify("wefree".getBytes(StandardCharsets.UTF_8),new String(sig),pubkey);
|
||||
System.out.println("用公钥验签结果: "+res);
|
||||
|
||||
// 导入证书
|
||||
// Certificate certificate=new Certificate();
|
||||
// certificate.
|
||||
// KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity()
|
||||
// .setCert();
|
||||
} catch (NoSuchPaddingException | NoSuchProviderException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | CertException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// // 取出当前身份
|
||||
// Identity curIden=KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity();
|
||||
// // 输出值
|
||||
// System.out.println("name: "+curIden.getName());
|
||||
// System.out.println("privatekey: "+ Arrays.toString(curIden.getPrikey().getBytes()));
|
||||
// System.out.println("pubkey: "+ Arrays.toString(curIden.getPubkey().getBytes()));
|
||||
// // 测试签名验签
|
||||
// byte[] signData;
|
||||
// try {
|
||||
// signData=curIden.sign("wefree".getBytes(StandardCharsets.UTF_8));
|
||||
// } catch (CryptoException e) {
|
||||
// e.printStackTrace();
|
||||
// return;
|
||||
// }
|
||||
// System.out.println(Arrays.toString(signData));
|
||||
// boolean raw;
|
||||
// try {
|
||||
// raw = curIden.verify("wefree1".getBytes(StandardCharsets.UTF_8),
|
||||
// signData);
|
||||
// } catch (IdentityException | AsymKeyException e) {
|
||||
// e.printStackTrace();
|
||||
// return;
|
||||
// }
|
||||
// System.out.println(raw);
|
||||
}
|
||||
}
|
||||
@@ -109,5 +109,15 @@ public class SM2PrivateKey implements PrivateKeyInterface {
|
||||
return signer.generateSignature();
|
||||
}
|
||||
|
||||
public BigInteger[] signNRS(byte[] content) throws CryptoException {
|
||||
SM2Signer_New signer = new SM2Signer_New();
|
||||
CipherParameters param = null;
|
||||
ParametersWithRandom pwr = new ParametersWithRandom(privateKey, new SecureRandom());
|
||||
param = pwr;
|
||||
signer.init(true, param);
|
||||
signer.update(content, 0, content.length);
|
||||
return signer.generateSignatureNRS();
|
||||
}
|
||||
|
||||
private ECPrivateKeyParameters privateKey;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
package minsecurity.crypto.sm2;
|
||||
|
||||
import org.bouncycastle.crypto.*;
|
||||
import org.bouncycastle.crypto.digests.SM3Digest;
|
||||
import org.bouncycastle.crypto.params.*;
|
||||
import org.bouncycastle.crypto.signers.DSAEncoding;
|
||||
import org.bouncycastle.crypto.signers.DSAKCalculator;
|
||||
import org.bouncycastle.crypto.signers.RandomDSAKCalculator;
|
||||
import org.bouncycastle.crypto.signers.StandardDSAEncoding;
|
||||
import org.bouncycastle.math.ec.*;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/*
|
||||
* @Author: Wang Feng
|
||||
* @Description:
|
||||
* @Version: 1.0.0
|
||||
* @Date: 16:00 2021/7/14
|
||||
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.bouncycastle.crypto.CipherParameters;
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
import org.bouncycastle.crypto.CryptoServicesRegistrar;
|
||||
import org.bouncycastle.crypto.Digest;
|
||||
import org.bouncycastle.crypto.Signer;
|
||||
import org.bouncycastle.crypto.digests.SM3Digest;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.crypto.params.ECKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ParametersWithID;
|
||||
import org.bouncycastle.crypto.params.ParametersWithRandom;
|
||||
import org.bouncycastle.math.ec.ECAlgorithms;
|
||||
import org.bouncycastle.math.ec.ECConstants;
|
||||
import org.bouncycastle.math.ec.ECFieldElement;
|
||||
import org.bouncycastle.math.ec.ECMultiplier;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
/**
|
||||
* The SM2 Digital Signature algorithm.
|
||||
*/
|
||||
public class SM2Signer_New
|
||||
implements Signer, ECConstants {
|
||||
private final DSAKCalculator kCalculator = new RandomDSAKCalculator();
|
||||
private final Digest digest;
|
||||
private final DSAEncoding encoding;
|
||||
|
||||
private ECDomainParameters ecParams;
|
||||
private ECPoint pubPoint;
|
||||
private ECKeyParameters ecKey;
|
||||
private byte[] z;
|
||||
|
||||
public SM2Signer_New() {
|
||||
this(StandardDSAEncoding.INSTANCE, new SM3Digest());
|
||||
}
|
||||
|
||||
public SM2Signer_New(Digest digest) {
|
||||
this(StandardDSAEncoding.INSTANCE, digest);
|
||||
}
|
||||
|
||||
public SM2Signer_New(DSAEncoding encoding) {
|
||||
this.encoding = encoding;
|
||||
this.digest = new SM3Digest();
|
||||
}
|
||||
|
||||
public SM2Signer_New(DSAEncoding encoding, Digest digest) {
|
||||
this.encoding = encoding;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public void init(boolean forSigning, CipherParameters param) {
|
||||
CipherParameters baseParam;
|
||||
byte[] userID;
|
||||
|
||||
if (param instanceof ParametersWithID) {
|
||||
baseParam = ((ParametersWithID) param).getParameters();
|
||||
userID = ((ParametersWithID) param).getID();
|
||||
|
||||
if (userID.length >= 8192) {
|
||||
throw new IllegalArgumentException("SM2 user ID must be less than 2^16 bits long");
|
||||
}
|
||||
} else {
|
||||
baseParam = param;
|
||||
// the default value, string value is "1234567812345678"
|
||||
userID = Hex.decodeStrict("31323334353637383132333435363738");
|
||||
}
|
||||
|
||||
if (forSigning) {
|
||||
if (baseParam instanceof ParametersWithRandom) {
|
||||
ParametersWithRandom rParam = (ParametersWithRandom) baseParam;
|
||||
|
||||
ecKey = (ECKeyParameters) rParam.getParameters();
|
||||
ecParams = ecKey.getParameters();
|
||||
kCalculator.init(ecParams.getN(), rParam.getRandom());
|
||||
} else {
|
||||
ecKey = (ECKeyParameters) baseParam;
|
||||
ecParams = ecKey.getParameters();
|
||||
kCalculator.init(ecParams.getN(), CryptoServicesRegistrar.getSecureRandom());
|
||||
}
|
||||
pubPoint = createBasePointMultiplier().multiply(ecParams.getG(), ((ECPrivateKeyParameters) ecKey).getD()).normalize();
|
||||
} else {
|
||||
ecKey = (ECKeyParameters) baseParam;
|
||||
ecParams = ecKey.getParameters();
|
||||
pubPoint = ((ECPublicKeyParameters) ecKey).getQ();
|
||||
}
|
||||
|
||||
z = getZ(userID);
|
||||
|
||||
digest.update(z, 0, z.length);
|
||||
}
|
||||
|
||||
public void update(byte b) {
|
||||
digest.update(b);
|
||||
}
|
||||
|
||||
public void update(byte[] in, int off, int len) {
|
||||
digest.update(in, off, len);
|
||||
}
|
||||
|
||||
public boolean verifySignature(byte[] signature) {
|
||||
try {
|
||||
BigInteger[] rs = encoding.decode(ecParams.getN(), signature);
|
||||
|
||||
return verifySignature(rs[0], rs[1]);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
digest.reset();
|
||||
|
||||
if (z != null) {
|
||||
digest.update(z, 0, z.length);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] generateSignature()
|
||||
throws CryptoException {
|
||||
byte[] eHash = digestDoFinal();
|
||||
|
||||
BigInteger n = ecParams.getN();
|
||||
BigInteger e = calculateE(n, eHash);
|
||||
BigInteger d = ((ECPrivateKeyParameters) ecKey).getD();
|
||||
|
||||
BigInteger r, s;
|
||||
|
||||
ECMultiplier basePointMultiplier = createBasePointMultiplier();
|
||||
|
||||
// 5.2.1 Draft RFC: SM2 Public Key Algorithms
|
||||
do // generate s
|
||||
{
|
||||
BigInteger k;
|
||||
do // generate r
|
||||
{
|
||||
// A3
|
||||
k = kCalculator.nextK();
|
||||
|
||||
// A4
|
||||
ECPoint p = basePointMultiplier.multiply(ecParams.getG(), k).normalize();
|
||||
|
||||
// A5
|
||||
r = e.add(p.getAffineXCoord().toBigInteger()).mod(n);
|
||||
}
|
||||
while (r.equals(ZERO) || r.add(k).equals(n));
|
||||
|
||||
// A6
|
||||
BigInteger dPlus1ModN = d.add(ONE).modInverse(n);
|
||||
|
||||
s = k.subtract(r.multiply(d)).mod(n);
|
||||
s = dPlus1ModN.multiply(s).mod(n);
|
||||
}
|
||||
while (s.equals(ZERO));
|
||||
|
||||
// A7
|
||||
try {
|
||||
return encoding.encode(ecParams.getN(), r, s);
|
||||
} catch (Exception ex) {
|
||||
throw new CryptoException("unable to encode signature: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger[] generateSignatureNRS()
|
||||
throws CryptoException {
|
||||
byte[] eHash = digestDoFinal();
|
||||
|
||||
BigInteger n = ecParams.getN();
|
||||
BigInteger e = calculateE(n, eHash);
|
||||
BigInteger d = ((ECPrivateKeyParameters) ecKey).getD();
|
||||
|
||||
BigInteger r, s;
|
||||
|
||||
ECMultiplier basePointMultiplier = createBasePointMultiplier();
|
||||
|
||||
// 5.2.1 Draft RFC: SM2 Public Key Algorithms
|
||||
do // generate s
|
||||
{
|
||||
BigInteger k;
|
||||
do // generate r
|
||||
{
|
||||
// A3
|
||||
k = kCalculator.nextK();
|
||||
|
||||
// A4
|
||||
ECPoint p = basePointMultiplier.multiply(ecParams.getG(), k).normalize();
|
||||
|
||||
// A5
|
||||
r = e.add(p.getAffineXCoord().toBigInteger()).mod(n);
|
||||
}
|
||||
while (r.equals(ZERO) || r.add(k).equals(n));
|
||||
|
||||
// A6
|
||||
BigInteger dPlus1ModN = d.add(ONE).modInverse(n);
|
||||
|
||||
s = k.subtract(r.multiply(d)).mod(n);
|
||||
s = dPlus1ModN.multiply(s).mod(n);
|
||||
}
|
||||
while (s.equals(ZERO));
|
||||
|
||||
// A7
|
||||
try {
|
||||
BigInteger[] bigIntegers=new BigInteger[3];
|
||||
bigIntegers[0]=ecParams.getN();
|
||||
bigIntegers[1]=r;
|
||||
bigIntegers[2]=s;
|
||||
return bigIntegers;
|
||||
// return encoding.encode(ecParams.getN(), r, s);
|
||||
} catch (Exception ex) {
|
||||
throw new CryptoException("unable to encode signature: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean verifySignature(BigInteger r, BigInteger s) {
|
||||
BigInteger n = ecParams.getN();
|
||||
|
||||
// 5.3.1 Draft RFC: SM2 Public Key Algorithms
|
||||
// B1
|
||||
if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// B2
|
||||
if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// B3
|
||||
byte[] eHash = digestDoFinal();
|
||||
|
||||
// B4
|
||||
BigInteger e = calculateE(n, eHash);
|
||||
|
||||
// B5
|
||||
BigInteger t = r.add(s).mod(n);
|
||||
if (t.equals(ZERO)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// B6
|
||||
ECPoint q = ((ECPublicKeyParameters) ecKey).getQ();
|
||||
ECPoint x1y1 = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), s, q, t).normalize();
|
||||
if (x1y1.isInfinity()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// B7
|
||||
BigInteger expectedR = e.add(x1y1.getAffineXCoord().toBigInteger()).mod(n);
|
||||
|
||||
return expectedR.equals(r);
|
||||
}
|
||||
|
||||
private byte[] digestDoFinal() {
|
||||
byte[] result = new byte[digest.getDigestSize()];
|
||||
digest.doFinal(result, 0);
|
||||
|
||||
reset();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private byte[] getZ(byte[] userID) {
|
||||
digest.reset();
|
||||
|
||||
addUserID(digest, userID);
|
||||
|
||||
addFieldElement(digest, ecParams.getCurve().getA());
|
||||
addFieldElement(digest, ecParams.getCurve().getB());
|
||||
addFieldElement(digest, ecParams.getG().getAffineXCoord());
|
||||
addFieldElement(digest, ecParams.getG().getAffineYCoord());
|
||||
addFieldElement(digest, pubPoint.getAffineXCoord());
|
||||
addFieldElement(digest, pubPoint.getAffineYCoord());
|
||||
|
||||
byte[] result = new byte[digest.getDigestSize()];
|
||||
|
||||
digest.doFinal(result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addUserID(Digest digest, byte[] userID) {
|
||||
int len = userID.length * 8;
|
||||
digest.update((byte) (len >> 8 & 0xFF));
|
||||
digest.update((byte) (len & 0xFF));
|
||||
digest.update(userID, 0, userID.length);
|
||||
}
|
||||
|
||||
private void addFieldElement(Digest digest, ECFieldElement v) {
|
||||
byte[] p = v.getEncoded();
|
||||
digest.update(p, 0, p.length);
|
||||
}
|
||||
|
||||
protected ECMultiplier createBasePointMultiplier() {
|
||||
return new FixedPointCombMultiplier();
|
||||
}
|
||||
|
||||
protected BigInteger calculateE(BigInteger n, byte[] message) {
|
||||
// TODO Should hashes larger than the order be truncated as with ECDSA?
|
||||
return new BigInteger(1, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import javax.crypto.NoSuchPaddingException;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@@ -107,6 +108,23 @@ public class Identity {
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger[] signNRS(byte[] content) throws CryptoException {
|
||||
if(this.Prikey == null)
|
||||
return null;
|
||||
switch (this.KeyParam.PublicKeyAlgorithm){
|
||||
case Common.SM2:
|
||||
SM2PrivateKey sm2PrivateKey = (SM2PrivateKey) this.Prikey;
|
||||
switch (this.KeyParam.SignatureAlgorithm){
|
||||
case Common.SM3withSM2:
|
||||
return sm2PrivateKey.signNRS(content);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 使用identity的公钥进行验签
|
||||
* 目前支持使用sm2公钥进行验签
|
||||
|
||||
@@ -4,9 +4,12 @@ import VMSConnection.Model.LoginWithSignRequest;
|
||||
import VMSConnection.Model.RegisterWithSignRequest;
|
||||
import VMSConnection.Security.BC_KeyManager;
|
||||
import VMSConnection.TCPNet.Message.NetworkResponse;
|
||||
import VMSConnection.Utils.Base64Helper;
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* @Author: Wang Feng
|
||||
@@ -16,28 +19,61 @@ import java.nio.charset.StandardCharsets;
|
||||
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
||||
*/
|
||||
public class TestAPI {
|
||||
// public static void main(String[] args){
|
||||
// String pubkey="042faa5f5ea00eca6dc8df7bd4c7abcbf0a9af20d56d69b4a463bfd0750ee77d7b" +
|
||||
// "9467e8815aa8e9b03106fa63cf85404a4999bcd874c7f64cf32908b2fbc37e17";
|
||||
// String base64sig="TUVZQ0lRRGZsZEw3RkRmem1lQlBNemxqbmxTVFFNeEJWU3JGUFY1Ql" +
|
||||
// "BfSDZiNzhRYlFJaEFLakpYRmRRUlZvX1l6TFVZY1lrS2N6U3hpcjNIdzhodnZmT1pFY3dfcWlw";
|
||||
//// String rawSig= new String(Base64Helper.BlockChain_Base64Decode_GoLanUn(base64sig));
|
||||
//// String rawSig="MEUCIFGGCE9qnvYemzJ1y_57CPopEbC_5SVSD2euqC0gzCfPAiEA7cS" +
|
||||
//// "hWuyUgrA95JuzMzTdylWUjOatgGWI68ig_IrAR5U";
|
||||
// String rawText="wefree7";
|
||||
//
|
||||
// BC_KeyManager bc=new BC_KeyManager();
|
||||
// bc.SetPubkey(pubkey);
|
||||
// boolean res=bc.Verify(rawText.getBytes(StandardCharsets.UTF_8),base64sig,pubkey);
|
||||
// System.out.println(res);
|
||||
// }
|
||||
public static void main(String[] args){
|
||||
String username="wefree3";
|
||||
String email="252553@qq.com";
|
||||
String username="wefree123";
|
||||
String email="2525532wws@qq.com";
|
||||
// 模拟客户端生成自己的公钥私钥
|
||||
BC_KeyManager bc_keyManager=new BC_KeyManager();
|
||||
bc_keyManager.GenKeyPair();
|
||||
String pubkey=bc_keyManager.GetPubkey();
|
||||
byte[] sig;
|
||||
try {
|
||||
sig = bc_keyManager.Sign(username.getBytes(StandardCharsets.UTF_8))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
sig = bc_keyManager.SignRaw(username.getBytes(StandardCharsets.UTF_8));
|
||||
// .getBytes(StandardCharsets.UTF_8);
|
||||
} catch (CryptoException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
// BigInteger[] sig;
|
||||
// try {
|
||||
// sig = bc_keyManager.SignNRS(username.getBytes(StandardCharsets.UTF_8));
|
||||
// } catch (CryptoException e) {
|
||||
// e.printStackTrace();
|
||||
// return;
|
||||
// }
|
||||
// System.out.println("sig N、R、S: "+ Arrays.toString(sig));
|
||||
|
||||
// 打印签名、base64编码后的签名、原始姓名
|
||||
System.out.println("rawsig: "+new String(sig));
|
||||
System.out.println("base64sig: "+Base64Helper.BlockChain_Base64Encode(sig));
|
||||
System.out.println("pubkey: "+pubkey);
|
||||
System.out.println("raw text: "+username);
|
||||
// return;
|
||||
|
||||
// 这里对sig进行一次base64编码
|
||||
// sig=Base64Helper.BlockChain_Base64Encode(sig).getBytes(StandardCharsets.UTF_8);
|
||||
//
|
||||
// 构造注册请求包 13294184003
|
||||
RegisterWithSignRequest request=new RegisterWithSignRequest(1,username,"password",
|
||||
"15239970973","1234",email,"dev","",
|
||||
pubkey,0,0,"1625142358",sig);
|
||||
try {
|
||||
System.out.println("login request: "+request.toJson());
|
||||
System.out.println("register request: "+request.toJson());
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -57,6 +93,11 @@ public class TestAPI {
|
||||
// 构造登录请求包
|
||||
LoginWithSignRequest loginWithSignRequest=new LoginWithSignRequest(username,
|
||||
"password",new String(networkResponse.Data),sig);
|
||||
try {
|
||||
System.out.println("login request: "+loginWithSignRequest.toJson());
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 登录
|
||||
NetworkResponse networkResponse2=bc_api.login(loginWithSignRequest);
|
||||
|
||||
Reference in New Issue
Block a user