From d09398cacf844960ec0391cbefb001399140a66e Mon Sep 17 00:00:00 2001 From: ChessNineeee <709030194@qq.com> Date: Thu, 8 Apr 2021 16:38:10 +0800 Subject: [PATCH] add:Keychain --- src/main/java/security/IdentifyManager.java | 6 +- src/main/java/security/KeyChain.java | 121 +++++++++++++++++++- src/main/java/security/SafeBag.java | 16 +++ src/test/java/security/KeyChainTest.java | 33 ++++++ 4 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 src/test/java/security/KeyChainTest.java diff --git a/src/main/java/security/IdentifyManager.java b/src/main/java/security/IdentifyManager.java index 5b42385..39930ff 100644 --- a/src/main/java/security/IdentifyManager.java +++ b/src/main/java/security/IdentifyManager.java @@ -22,7 +22,11 @@ import java.util.concurrent.ConcurrentMap; // TODO: 测试 public class IdentifyManager { - private final ConcurrentMap identifies; // 一个map,存储了身份名字和网络身份实体的映射 + public void setIdentifies(ConcurrentMap identifies) { + this.identifies = identifies; + } + + private ConcurrentMap identifies; // 一个map,存储了身份名字和网络身份实体的映射 private Identity defaultIdentity; // 默认网络身份 private int privateKeyEncryptionAlgorithm; // 对秘钥加密所使用的加密算法 diff --git a/src/main/java/security/KeyChain.java b/src/main/java/security/KeyChain.java index 4b6a7f9..a080e87 100644 --- a/src/main/java/security/KeyChain.java +++ b/src/main/java/security/KeyChain.java @@ -1,7 +1,19 @@ package security; +import component.Signature; +import component.SignatureValue; +import encoding.Block; +import encoding.SelfEncodingBase; import minsecurity.identity.Identity; import minsecurity.identity.IdentityException; +import packet.CPacket; +import packet.Data; +import packet.Interest; +import packet.MINPacket; + +import java.lang.reflect.Array; +import java.util.IdentityHashMap; + /* * @Author: hongyu guo * @Description: 用于给网络包签名和验签 @@ -10,6 +22,22 @@ import minsecurity.identity.IdentityException; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ public class KeyChain { + public IdentifyManager getIdentifyManager() { + return identifyManager; + } + + public void setIdentifyManager(IdentifyManager identifyManager) { + this.identifyManager = identifyManager; + } + + public Identity getCurrentIdentity() { + return currentIdentity; + } + + public void setCurrentIdentity(Identity currentIdentity) { + this.currentIdentity = currentIdentity; + } + private IdentifyManager identifyManager; private Identity currentIdentity; @@ -23,7 +51,6 @@ public class KeyChain { public KeyChain(){ identifyManager = new IdentifyManager(); currentIdentity = identifyManager.getDefaultIdentity(); - // TODO: 考虑是否需要在没有默认身份的时候创建一个缺省的本地网络身份 } @@ -79,10 +106,94 @@ public class KeyChain { } - // TODO: packet类暂未完成 - // public void getIdentifierAndReadOnlyValueFromPacket(){ - // - // } + //TODO: packet类暂未完成 + private byte[] getIdentifierAndReadOnlyValueFromPacket(MINPacket packet) throws Exception{ + Block iBlock = new SelfEncodingBase().selfWireEncode(packet.identifierField); + Block rBlock = new SelfEncodingBase().selfWireEncode(packet.readOnlyField); + byte[] iBlockValue = iBlock.getValue(); + byte[] rBlockValue = rBlock.getValue(); + byte[] rawData = new byte[iBlockValue.length + rBlockValue.length]; + System.arraycopy(iBlockValue, 0, rawData, 0, iBlockValue.length); + System.arraycopy(rBlockValue, 0, rawData, iBlockValue.length, rBlockValue.length); + + return rawData; + } + + public void sign(MINPacket packet) throws Exception{ + // 首先检查当前使用的身份是否可以用来签名 + checkIdentifyCanUseToSign(this.currentIdentity); + + // 1. 提取标识区和只读区的值,对其进行签名 + byte[] rawData = getIdentifierAndReadOnlyValueFromPacket(packet); + + // 2. 对标识区和只读区进行签名 + byte[] signResult = this.currentIdentity.sign(rawData); + + // 3. 往包签名区中添加签名 + Signature signature = new Signature(this.currentIdentity, signResult); + packet.signatureField.addSignature(signature); + } + + public void signCPacket(CPacket cPacket) throws Exception{ + cPacket.fillDataToFields(); + this.sign(cPacket.minPacket); + } + + public void signInterest(Interest interest) throws Exception{ + interest.fillDataToFields(); + this.sign(interest.minPacket); + } + + public void signData(Data data) throws Exception{ + data.fillDataToFields(); + this.sign(data.minPacket); + } + + public void verify(MINPacket minPacket) throws Exception{ + // 提取签名区的第一个签名进行验证(认为签名区的第一个签名为包的签名,包含标识区和只读区签名) + Signature signature = minPacket.signatureField.getSignature(0); + + String identityName = signature.getSigInfo().getKeyLocator().getIdentifier().toUri(); + Identity identity = this.identifyManager.getIdentityByName(identityName); + + if (identity == null){ + throw new KeyChainException("Verify failed, could not find the identity"); + } + + byte[] rawData = getIdentifierAndReadOnlyValueFromPacket(minPacket); + identity.verify(rawData, signature.getSigValue().getValue()); + } + + public void verifyCPacket(CPacket packet) throws Exception{ + packet.fillDataToFields(); + verify(packet.minPacket); + } + + public void verifyInterest(Interest interest) throws Exception{ + interest.fillDataToFields(); + verify(interest.minPacket); + } + + public void verifyData(Data data) throws Exception{ + data.fillDataToFields(); + verify(data.minPacket); + } + + public SafeBag exportSafeBag(Identity identity, String passwd) throws Exception{ + byte[] res = identity.dump(passwd); + SafeBag safeBag = new SafeBag(res); + return safeBag; + } + + public void importSafeBag(SafeBag safeBag, String passwd, boolean force) throws Exception{ + Identity identity = Identity.load(safeBag.getValue(), passwd); + + if (!this.identifyManager.existIdentity(identity.getName()) || force){ + this.identifyManager.saveIdentity(identity, force, false); + }else { + throw new KeyChainException(String.format("Identify %s is already exists!", identity.getName())); + } + } } diff --git a/src/main/java/security/SafeBag.java b/src/main/java/security/SafeBag.java index 6a3e4e9..11ac111 100644 --- a/src/main/java/security/SafeBag.java +++ b/src/main/java/security/SafeBag.java @@ -8,5 +8,21 @@ package security; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ public class SafeBag { + public byte[] getValue() { + return value; + } + + public void setValue(byte[] value) { + this.value = value; + } + private byte[] value; + + public SafeBag(){ + + } + + public SafeBag(byte[] value){ + this.value = value; + } } diff --git a/src/test/java/security/KeyChainTest.java b/src/test/java/security/KeyChainTest.java new file mode 100644 index 0000000..69d1de7 --- /dev/null +++ b/src/test/java/security/KeyChainTest.java @@ -0,0 +1,33 @@ +package security; + +import minsecurity.Common; +import minsecurity.identity.Identity; +import org.junit.Test; + +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +public class KeyChainTest { + @Test + public void testCreateKeyChain(){ + try{ + KeyChain keyChain = new KeyChain(); + Identity identity = new Identity(); + identity.setName("wzq"); + identity.setPasswd("123456123456"); + + ConcurrentHashMap identityHashMap = new ConcurrentHashMap<>(); + identityHashMap.put("/wzq", identity); + + keyChain.getIdentifyManager().setIdentifies(identityHashMap); + keyChain.getIdentifyManager().setDefaultIdentity(identity); + + String passwd = "2DD29CA851E7B56E"; + Identity identity1 = keyChain.getIdentifyManager().createIdentityByName("/wzq1", passwd, false); + identity1.unLock(passwd, Common.SM4ECB); + System.out.println(identity1.getPrikey()); + }catch (Exception ex){ + System.out.println(ex.getMessage()); + } + } +}