From bcd906e1a202d60571a2e5cfd660eb3123275006 Mon Sep 17 00:00:00 2001 From: ChessNineeee <709030194@qq.com> Date: Sat, 10 Apr 2021 16:27:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:IdentifyManager=20sqlite=E9=87=8D=E5=86=99?= =?UTF-8?q?=20todo:=20=E6=9B=B4=E6=96=B0identity=E4=B8=AD=E7=9A=84lock?= =?UTF-8?q?=E4=B8=8Eunlock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../minsecurity/crypto/sm2/SM2PrivateKey.java | 4 +- .../java/minsecurity/identity/Identity.java | 14 +++- src/main/java/security/IdentifyManager.java | 70 ++++++++++++++----- src/main/java/security/KeyChain.java | 19 ++++- .../identity/sqlite/db/DBTest.java | 70 +++++++++---------- 5 files changed, 120 insertions(+), 57 deletions(-) diff --git a/src/main/java/minsecurity/crypto/sm2/SM2PrivateKey.java b/src/main/java/minsecurity/crypto/sm2/SM2PrivateKey.java index 9425377..08bcecf 100644 --- a/src/main/java/minsecurity/crypto/sm2/SM2PrivateKey.java +++ b/src/main/java/minsecurity/crypto/sm2/SM2PrivateKey.java @@ -72,8 +72,8 @@ public class SM2PrivateKey implements PrivateKeyInterface { * @return boolean */ public boolean setBytes(byte[] d){ - if (d.length != 64) - return false; +// if (d.length != 64) +// return false; String priStr = new String(d); privateKey = new ECPrivateKeyParameters(new BigInteger(priStr, 16), SM2Base.DOMAIN_PARAMS); return true; diff --git a/src/main/java/minsecurity/identity/Identity.java b/src/main/java/minsecurity/identity/Identity.java index b3c39c5..4bd3f05 100644 --- a/src/main/java/minsecurity/identity/Identity.java +++ b/src/main/java/minsecurity/identity/Identity.java @@ -12,6 +12,7 @@ import minsecurity.crypto.sm2.SM2PublicKey; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.jcajce.provider.digest.SM3; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.slf4j.LoggerFactory; @@ -20,6 +21,7 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.IOException; import java.io.Serializable; +import java.lang.reflect.Array; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -244,12 +246,20 @@ public class Identity { } // TODO: passwd ??? - public boolean unLock(String passwd, int algo) throws IdentityException { + public boolean unLock(String passwd, int algo) throws IdentityException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidKeyException { switch (algo) { case Common.SM4ECB: if(passwd == null || passwd.length() == 0) return false; - PrivateKeyInterface privateKey = KeyUtils.unMarshalPrivateKey(PrikeyRawByte, KeyParam.PublicKeyAlgorithm); + + 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); Prikey = privateKey; PrikeyRawByte = null; return true; diff --git a/src/main/java/security/IdentifyManager.java b/src/main/java/security/IdentifyManager.java index 39930ff..3fde6c2 100644 --- a/src/main/java/security/IdentifyManager.java +++ b/src/main/java/security/IdentifyManager.java @@ -7,9 +7,13 @@ import minsecurity.identity.Identity; import minsecurity.identity.IdentityException; import minsecurity.identity.KeyParam; import minsecurity.identity.persist.MapDB; +import minsecurity.identity.persist.Persist; +import minsecurity.identity.persist.sqlite.Sqlite; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /* @@ -40,11 +44,28 @@ public class IdentifyManager { * @date 2021/3/11 **/ public IdentifyManager(){ - MapDB mapDB = MapDB.getInstance(); - // TODO: 目前使用浅拷贝, 是否需要修改为深拷贝? - this.identifies = mapDB.getIdentityMap(); - this.defaultIdentity = MapDB.getInstance().getDefaultIdentity(); - this.privateKeyEncryptionAlgorithm = Common.SM4ECB; + try{ + this.identifies = loadAllIdentifies(); + this.defaultIdentity = Persist.getDefaultIdentityFromStorage(""); + this.privateKeyEncryptionAlgorithm = Common.SM4ECB; + }catch (Exception ex){ + System.out.println(String.format("创建IdentifyManager实例失败:%s", ex.getMessage())); + } + } + + /** + * 从sqlite中加载全部网络身份信息并封装成ConcurrentMap + * @return {ConcurrentMap} + * @throws Exception + */ + private ConcurrentMap loadAllIdentifies() throws Exception{ + List identities = Persist.getAllIdentityFromStorage(""); + ConcurrentHashMap res = new ConcurrentHashMap<>(); + for (Identity id: + identities) { + res.put(id.getName(), id); + } + return res; } @@ -56,7 +77,7 @@ public class IdentifyManager { * @date 2021/3/11 **/ public Identity getIdentityByName(String name){ - return MapDB.getInstance().getIdentityByName(name); + return identifies.get(name); } /** @@ -68,9 +89,12 @@ public class IdentifyManager { * @author hongyu guo * @date 2021/3/11 **/ - public boolean deleteIdentityByName(String name, boolean commit){ - Identity identity = MapDB.getInstance().deleteIdentity(name, commit); - return identity != null; + public boolean deleteIdentityByName(String name, boolean commit) throws Exception { + // 从内存中删除掉它 + this.identifies.remove(name); + // 从sqlite中删除掉它 + Persist.deleteIdentityByNameFromStorage(name); + return true; } /** @@ -85,12 +109,19 @@ public class IdentifyManager { * @author hongyu guo * @date 2021/3/11 **/ - public boolean saveIdentity(Identity newIdentity, boolean force, boolean commit){ + public boolean saveIdentity(Identity newIdentity, boolean force, boolean commit) throws Exception { // identifies.con if(identifies.containsKey(newIdentity.getName()) && !force) { return false; } - MapDB.getInstance().addIdentity(newIdentity.getName(), newIdentity, commit); + // 身份不存在,或者存在但是指定强制覆盖,则保存该网络身份 + + // 将新的网络身份进行持久化存储 + // TODO 目前的Persist模块无法实现强制覆盖,因为会抛出重名异常 + Persist.persistIdentity(newIdentity); + + // 同时更新内存中数据 + this.identifies.put(newIdentity.getName(), newIdentity); return true; } @@ -108,7 +139,7 @@ public class IdentifyManager { * @author hongyu guo * @date 2021/3/11 **/ - public Identity createIdentityByNameAndKeyParam(String name, KeyParam keyParam, String passwd, boolean commit){ + public Identity createIdentityByNameAndKeyParam(String name, KeyParam keyParam, String passwd, boolean commit) throws Exception { if(identifies.containsKey(name)){ return null; } @@ -123,7 +154,11 @@ public class IdentifyManager { e.printStackTrace(); } } - return MapDB.getInstance().addIdentity(name, newIdentity, commit); + // 将新生成的网络身份进行持久化存储 + Persist.persistIdentity(newIdentity); + // 持久化存储成功则在内存中也存储一份 + this.identifies.put(name, newIdentity); + return newIdentity; } /** @@ -139,7 +174,7 @@ public class IdentifyManager { * @author hongyu guo * @date 2021/3/11 **/ - public Identity createIdentityByName(String name, String passwd, boolean commit){ + public Identity createIdentityByName(String name, String passwd, boolean commit) throws Exception { return createIdentityByNameAndKeyParam(name, new KeyParam(Common.SM2, Common.SM3withSM2), passwd, commit); } @@ -151,11 +186,12 @@ public class IdentifyManager { * @author hongyu guo * @date 2021/3/11 **/ - public boolean setDefaultIdentity(Identity identity, boolean commit) { - if(identity == null) + public boolean setDefaultIdentity(Identity identity, boolean commit) throws Exception { + if (identity == null) return false; this.defaultIdentity = identity; - return MapDB.getInstance().setDefaultIdentity(identity.getName(), commit); + Persist.setDefaultIdentityByNameInStorage(identity.getName()); + return true; } /** diff --git a/src/main/java/security/KeyChain.java b/src/main/java/security/KeyChain.java index a080e87..7dbf0bf 100644 --- a/src/main/java/security/KeyChain.java +++ b/src/main/java/security/KeyChain.java @@ -11,7 +11,13 @@ import packet.Data; import packet.Interest; import packet.MINPacket; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import java.lang.reflect.Array; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.util.IdentityHashMap; /* @@ -68,6 +74,18 @@ public class KeyChain { identity.unLock(passwd, identifyManager.getPrivateKeyEncryptionAlgorithm()); } catch (IdentityException e) { e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); } } @@ -106,7 +124,6 @@ public class KeyChain { } - //TODO: packet类暂未完成 private byte[] getIdentifierAndReadOnlyValueFromPacket(MINPacket packet) throws Exception{ Block iBlock = new SelfEncodingBase().selfWireEncode(packet.identifierField); Block rBlock = new SelfEncodingBase().selfWireEncode(packet.readOnlyField); diff --git a/src/test/java/minsecurity/identity/sqlite/db/DBTest.java b/src/test/java/minsecurity/identity/sqlite/db/DBTest.java index 5dd2480..c71c389 100644 --- a/src/test/java/minsecurity/identity/sqlite/db/DBTest.java +++ b/src/test/java/minsecurity/identity/sqlite/db/DBTest.java @@ -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()); +// 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); - 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 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());