完善了VPNLoginExample;去tmd证书导入导出

This commit is contained in:
free will committed 2021-07-15 16:53:37 +08:00
1 parent 892171eba9
commit e56bb70fb6
8 files changed
+434 -96

No files matched your search

@@ -105,7 +105,7 @@ public class BC_KeyManager {
*/
public String Sign(byte[] text) throws CryptoException {
byte[] sig=this.prk.sign(text);
return Base64Helper.BlockChain_Base64Encode(sig);
return Base64Helper.Base64UrlEncode(sig);
}
public byte[] SignRaw(byte[] text) throws CryptoException {
@@ -127,7 +127,7 @@ public class BC_KeyManager {
* @return
*/
public boolean Verify(byte[] text,String signature,String pubkey){
byte[] sig=Base64Helper.BlockChain_Base64Decode(signature);
byte[] sig=Base64Helper.Base64UrlDecode(signature);
SM2PublicKey publicKey=new SM2PublicKey();
boolean flag=publicKey.setBytes(pubkey.getBytes(StandardCharsets.UTF_8));
@@ -6,36 +6,78 @@ import java.util.Base64;
/*
* @Author: Wang Feng
* @Description:
* 基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
* URL:输出被映射到一组字符A-Za-z0-9+_,输出是URL和文件。
* MIME:输出隐射到MIME友好格式。输出每行不超过76字符,并且使用'\r'并跟随'\n'作为分割。编码输出最后没有行分割。
* @Version: 1.0.0
* @Date: 22:20 2021/6/22
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class Base64Helper {
/**
* 与vpn-management适配的base64编码
* base64基本编解码 & 没有补全
* @param src
* @return
*/
public static String BlockChain_Base64Encode(byte[] src){
public static String Base64BasicEncode(byte[] src){
Base64.Encoder encoder = Base64.getEncoder();
encoder = encoder.withoutPadding();
return encoder.encodeToString(src);
}
public static String Base64BasicEncode(String src){
return Base64BasicEncode(src);
}
public static byte[] Base64BasicDecode(String src) {
Base64.Decoder decoder = Base64.getDecoder();
return decoder.decode(src.getBytes(StandardCharsets.UTF_8));
}
/**
* 与vpn-management适配的base64编码
* url编解码 & 没有补全
* @param src
* @return
*/
public static String Base64UrlEncode(byte[] src){
Base64.Encoder encoder = Base64.getUrlEncoder();
encoder = encoder.withoutPadding();
return encoder.encodeToString(src);
}
public static String BlockChain_Base64Encode(String src){
return BlockChain_Base64Encode(src.getBytes(StandardCharsets.UTF_8));
public static String Base64UrlEncode(String src){
return Base64UrlEncode(src.getBytes(StandardCharsets.UTF_8));
}
/**
* 与vpn-management适配的base64解码
* url编解码 & 没有补全
* @param src
* @return
*/
public static byte[] BlockChain_Base64Decode(String src) {
public static byte[] Base64UrlDecode(String src) {
Base64.Decoder decoder = Base64.getUrlDecoder();
return decoder.decode(src.getBytes(StandardCharsets.UTF_8));
}
/**
* 与ppov适配的base64编解码格式
* 用户身份编解码格式,如用户名为username,其用户身份标识则为"/"+Base64PlusEncode(username)
* mime编解码,加了=/替换
*/
public static String Base64PlusEncode(String srcStr){
String dstStr = "" ;
dstStr = Base64.getMimeEncoder().encodeToString(srcStr.getBytes(StandardCharsets.UTF_8));
dstStr = dstStr.replaceAll("=","-").replaceAll("/","_") ;
return dstStr;
}
public static String Base64PlusDecode(String srcStr){
srcStr = srcStr.replaceAll("_","/").replaceAll("-","=") ;
byte[] dstStrByte = null;
dstStrByte = Base64.getMimeDecoder().decode(srcStr.getBytes(StandardCharsets.UTF_8));
return new String(dstStrByte);
}
/**
* 参考链接: https://blog.csdn.net/qq_36928715/article/details/110489464
* golang的Unmarshal函数,自动把结构体中的base64转成了byte[],这里填补java的此功能
+146 -78
View File
@@ -1,6 +1,10 @@
package examples;
import VMSConnection.BC_API;
import VMSConnection.Model.LoginWithSignRequest;
import VMSConnection.Model.RegisterWithSignRequest;
import VMSConnection.Security.BC_KeyManager;
import VMSConnection.TCPNet.Message.NetworkResponse;
import VMSConnection.Utils.Base64Helper;
import minsecurity.certificate.cert.CertException;
import minsecurity.certificate.cert.Certificate;
@@ -14,10 +18,7 @@ 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.security.*;
import java.util.Arrays;
/*
@@ -29,89 +30,156 @@ import java.util.Arrays;
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class VPNLoginExample {
public String username="wefree";
// 身份信息保存位置
public static String identityPath="D:\\TEST\\Identitys\\";
// 用户名
public static String username="/freewill";
// VMS发送来的证书的密码
public static byte[] certPasswd="123456".getBytes(StandardCharsets.UTF_8);
// 基于用户名的用户身份标识
public static String identityName="/"+Base64Helper.Base64PlusEncode(username);
// 注册用户的IP
public static String vms_ip="121.15.171.91";
// 注册邮箱
public static String email="2555627323s@163.com";
// 生成本地密钥,持久化存储那种
private void generateForeverIdentity(){
KeyManagerExample.INSTANCE.initKeyChain("/"+username,"D:\\TEST\\Identitys\\");
/**
* 生成本地密钥,持久化存储到本地硬盘
* @param username
* @param identityPath
*/
public void generateForeverIdentity(String username,String identityPath){
// identityName是将username进行base64编码,然后加上"/"
String identityName="/"+Base64Helper.Base64PlusEncode(username);
KeyManagerExample.INSTANCE.initKeyChain(identityName,identityPath);
}
// 导出证书
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";
// 使用
/**
* 使用KeyChain的当前用户身份的私钥对指定字节数组进行签名
* @param bytes
* @return
*/
public byte[] signBytes(byte[] bytes){
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;
}
return KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity().sign(bytes);
} catch (CryptoException e) {
e.printStackTrace();
return null;
}
}
public byte[] signBytes(String bytes){
return signBytes(bytes.getBytes(StandardCharsets.UTF_8));
}
// sig用base64编码一次
sig= Base64Helper.BlockChain_Base64Encode(sig).getBytes(StandardCharsets.UTF_8);
/**
* 导入进行用户注册时VMS返回的证书
* @param certString
* @param certPasswd 默认是123456
* @return
*/
public boolean importVMSCert(byte[] certString,byte[] certPasswd){
try {
return KeyManagerExample.INSTANCE.getKeyChain().getIdentifyManager()
.importCert(certString,certPasswd);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean importVMSCert(String certString,byte[] certPasswd){
return importVMSCert(certString.getBytes(StandardCharsets.UTF_8),certPasswd);
}
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);
/**
* 取出指定身份标识的VMS证书
* @param identityName
* @param certPasswd 默认123456
* @return
*/
public String exportVMSCert(String identityName,byte[] certPasswd){
try {
return KeyManagerExample.INSTANCE.getKeyChain().getIdentifyManager()
.dumpCert(identityName, certPasswd);
} catch (NoSuchPaddingException | InvalidKeyException | CertException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
return null;
}
}
public String exportVMSCert(byte[] certPasswd){
// 取出当前用户的身份标识名称
String identityName=KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity()
.getName();
System.out.println("!!!: "+identityName);
return exportVMSCert(identityName,certPasswd);
}
// 导入证书
// Certificate certificate=new Certificate();
// certificate.
// KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity()
// .setCert();
} catch (NoSuchPaddingException | NoSuchProviderException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | CertException | InvalidKeyException e) {
/**
* 模拟用户在VMS上的注册
*/
public void testRegister(){
// 1. 生成用户的公钥私钥(有则直接取出)
VPNLoginExample vpnExample=new VPNLoginExample();
vpnExample.generateForeverIdentity(username,identityPath);
// 2. 签名(签名用户名) & 公钥(用户本地保存的公钥)
byte[] registerSign= vpnExample.signBytes(username);
String pubKey=new String(KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity().getPubkey()
.getBytes());
// 3. 构造注册请求包
RegisterWithSignRequest request=new RegisterWithSignRequest(1,username,"password",
"15239970973","1234",email,"dev","",
pubKey,0,0,"1625142358",registerSign);
// 4. 调用bc-api,进行注册
BC_API bc_api=new BC_API();
bc_api.ip=vms_ip;
// 注册
NetworkResponse networkResponse=bc_api.register(request);
try {
System.out.println("注册应答: "+networkResponse.toJson());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(networkResponse.Code);
// // 取出当前身份
// 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);
// 5. 保存注册应答中的证书到本地
boolean flag=vpnExample.importVMSCert(networkResponse.Data,certPasswd);
System.out.println("保存证书应答: "+flag);
}
/**
* 模拟用户在VMS上的登录
*/
public void testLogin(){
// 1. 生成用户的公钥私钥(有则直接取出)
VPNLoginExample vpnExample=new VPNLoginExample();
vpnExample.generateForeverIdentity(username,identityPath);
// 2. 签名(签名用户名) & 证书(用户本地保存的证书,注册时接收到的VMS数据)
byte[] loginSign= vpnExample.signBytes(username);
String cert=vpnExample.exportVMSCert(certPasswd);
// 3. 构造登录请求包
LoginWithSignRequest loginWithSignRequest=new LoginWithSignRequest(username,
"password",cert,loginSign);
// 4. 调用bc-api,进行登录
BC_API bc_api=new BC_API();
bc_api.ip=vms_ip;
// 登录
NetworkResponse networkResponse=bc_api.login(loginWithSignRequest);
try {
System.out.println("登录应答: "+networkResponse.toJson());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(networkResponse.Code);
}
// 测试注册登录
public static void main(String[] args){
new VPNLoginExample().testRegister();
new VPNLoginExample().testLogin();
}
}
@@ -1,5 +1,6 @@
package minsecurity.certificate.cert;
import VMSConnection.Utils.Base64Helper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import common.LoggerHelper;
@@ -261,11 +262,13 @@ public class CertUtils {
switch (symAlgoMode){
case Common.SM4CBC:{
System.out.println("SM4CBC");
// TODO: PADDING??? IV?????
ret = SM4.encrypt_CBC_Padding(sm4Key, new byte[16],bytesOfCert);
break;
}
case Common.SM4ECB:{
System.out.println("SM4ECB");
ret = SM4.encrypt_ECB_Padding(sm4Key, bytesOfCert);
break;
}
@@ -275,6 +278,13 @@ public class CertUtils {
} else {
ret = bytesOfCert;
}
System.out.println("raw cert dump length: "+ret.length);
System.out.println("base64helper basic: "+ Base64Helper.Base64BasicEncode(ret));
System.out.println("base64helper basic-len: "+Base64Helper.Base64BasicEncode(ret).length());
System.out.println("base64helper url: "+ Base64Helper.Base64UrlEncode(ret));
System.out.println("base64helper url-len: "+Base64Helper.Base64UrlEncode(ret).length());
System.out.println("Base64Plus-len: "+Base64Helper.Base64PlusEncode(new String(ret)).length());
System.out.println("Base64Plus: "+Base64Helper.Base64PlusEncode(new String(ret)));
return Base64.getEncoder().encodeToString(ret);
}
@@ -303,6 +313,7 @@ public class CertUtils {
bytesOfCert = SM4.decrypt_CBC_Padding(sm4Key,new byte[16], bytesOfPem);
break;
case Common.SM4ECB:
System.out.println("frompem: SM4ECB");
bytesOfCert = SM4.decrypt_ECB_Padding(sm4Key, bytesOfPem);
break;
default:
+60 -2
View File
@@ -1,5 +1,6 @@
package security;
import common.LoggerHelper;
import minsecurity.Common;
import minsecurity.certificate.cert.CertException;
import minsecurity.certificate.cert.CertUtils;
@@ -397,13 +398,56 @@ public class IdentityManager {
return "";
}
if (targetIdentity.getCert() == null ||
(targetIdentity.getCert().getIssuer().equals("") && targetIdentity.getCert().getSignature() == null)) {
if(targetIdentity.getCert() == null){
return "";
}
if(targetIdentity.getCert().getIssuer()==null){
return "";
}
if((targetIdentity.getCert().getIssuer().equals(""))
&&(targetIdentity.getCert().getSignature() == null)) {
return "";
}
System.out.println(targetIdentity.getCert());
return CertUtils.toPem(targetIdentity.getCert(), "".getBytes(), Common.SM4ECB);
}
/**
* 使用密码导出证书
* @param identityName
* @param passwd
* @return
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws CertException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws InvalidAlgorithmParameterException
*/
public String dumpCert(String identityName,byte[] passwd) throws NoSuchPaddingException, InvalidKeyException, CertException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
Identity targetIdentity = getIdentityByName(identityName);
if(targetIdentity == null) {
return "";
}
if(targetIdentity.getCert() == null){
return "";
}
if(targetIdentity.getCert().getIssuer()==null){
return "";
}
if((targetIdentity.getCert().getIssuer().equals(""))
&&(targetIdentity.getCert().getSignature() == null)) {
return "";
}
System.out.println(targetIdentity.getCert());
return CertUtils.toPem(targetIdentity.getCert(), passwd, Common.SM4ECB);
}
/**
* 导入证书
* @param bytesOfCert
@@ -414,6 +458,20 @@ public class IdentityManager {
**/
public boolean importCert(byte[] bytesOfCert) throws Exception {
Certificate cert = CertUtils.fromPem(new String(bytesOfCert), null, Common.SM4ECB);
LoggerHelper.info("importing cert: "+cert.toString());
return loadCert(cert.getIssueTo(), cert);
}
/**
* 导入有密码的证书
* @param bytesOfCert
* @param passwd
* @return
* @throws Exception
*/
public boolean importCert(byte[] bytesOfCert,byte[] passwd) throws Exception {
Certificate cert = CertUtils.fromPem(new String(bytesOfCert), passwd, Common.SM4ECB);
LoggerHelper.info("importing cert: "+cert.toString());
return loadCert(cert.getIssueTo(), cert);
}