Files
min-dev-java/src/main/java/minsecurity/identity/Identity.java
T
2021-03-09 22:00:57 +08:00

271 lines
8.8 KiB
Java

package minsecurity.identity;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import minsecurity.Common;
import minsecurity.certificate.cert.CertException;
import minsecurity.certificate.cert.Certificate;
import minsecurity.crypto.KeyUtils;
import minsecurity.crypto.PrivateKeyInterface;
import minsecurity.crypto.PublicKeyInterface;
import minsecurity.crypto.SM4;
import minsecurity.crypto.sm2.SM2PrivateKey;
import minsecurity.crypto.sm2.SM2PublicKey;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.Serializable;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import java.util.Base64;
/*
* @Author: hongyu guo
* @Description:
* @Version: 1.0.0
* @Date: 20:25 2021/03/07
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class Identity {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Identity.class);
private String Name;
private KeyParam KeyParam;
private PrivateKeyInterface Prikey;
private byte[] PrikeyRawByte;
private PublicKeyInterface Pubkey;
private String Passwd;
private Certificate Cert;
private boolean IsDefault;
public Identity(String name, KeyParam keyParam,
PrivateKeyInterface prikey, byte[] prikeyRawByte,
PublicKeyInterface pubkey, String passwd, Certificate cert,
boolean isDefault) {
Name = name;
KeyParam = keyParam;
Prikey = prikey;
PrikeyRawByte = prikeyRawByte;
Pubkey = pubkey;
Passwd = passwd;
Cert = cert;
IsDefault = isDefault;
}
public Identity(){}
public byte[] sign(byte[] digest) 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.sign(digest);
default:
return null;
}
default:
return null;
}
}
public boolean verify(byte[] msg, byte[] digest) {
if(this.Pubkey == null)
return false;
switch (this.KeyParam.PublicKeyAlgorithm){
case Common.SM2:
SM2PublicKey sm2PublicKey = (SM2PublicKey) this.Pubkey;
switch (this.KeyParam.SignatureAlgorithm){
case Common.SM3withSM2:
return sm2PublicKey.verify(msg, digest);
default:
return false;
}
default:
return false;
}
}
public byte[] decrypt(byte[] cipher) throws InvalidCipherTextException {
if(this.Prikey == null)
return null;
return this.Prikey.decrypt(cipher);
}
public byte[] encrypt(byte[] content) throws InvalidCipherTextException {
if(this.Pubkey == null)
return null;
return this.Pubkey.encrypt(content);
}
public byte[] dump(String passwd) throws NoSuchPaddingException, InvalidAlgorithmParameterException, CertException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
InnerIdentity innerIdentity = IdentityUtil.parseIdentityToInner(this);
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);
}
return Base64.getEncoder().encode(bytesOfInnerIdentity);
}
public static Identity load(byte[] data, String passwd)
throws BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException,
NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchProviderException,
InvalidKeyException, CertException {
byte[] bytesOfIdentity = Base64.getDecoder().decode(data);
byte[] plain;
if(passwd != null && passwd.length() != 0){
byte[] sm4Key = KeyUtils.get16bytePasswd(passwd.getBytes());
plain = SM4.decrypt_CBC_Padding(sm4Key, new byte[16], bytesOfIdentity);
} else{
plain = bytesOfIdentity;
}
ObjectMapper mapper = new ObjectMapper();
InnerIdentity innerIdentity = null;
// logger.debug(ByteUtils.toHexString(plain));
try {
innerIdentity = mapper.readValue(plain, InnerIdentity.class);
} catch (IOException e) {
e.printStackTrace();
}
return IdentityUtil.parseInnerToIdentity(innerIdentity);
}
// TODO: passwd ???
public boolean lock(String passwd, int algo) throws IdentityException {
switch (algo){
case Common.SM4ECB:
if (passwd.length() != 16){
throw new IdentityException("密码应为16位");
}
PrikeyRawByte = Prikey.getBytes();
Prikey = null;
return true;
default:
return false;
}
}
public boolean isLocked(){
return PrikeyRawByte != null && PrikeyRawByte.length > 0;
}
// TODO: passwd ???
public boolean unLock(String passwd, int algo) throws IdentityException {
switch (algo) {
case Common.SM4ECB:
if(passwd == null || passwd.length() == 0)
return false;
PrivateKeyInterface privateKey = KeyUtils.unMarshalPrivateKey(PrikeyRawByte, KeyParam.PublicKeyAlgorithm);
Prikey = privateKey;
PrikeyRawByte = null;
return true;
default:
throw new IdentityException("未知对称加密算法");
}
}
public boolean hasPrivateKey() {
return Prikey != null || (PrikeyRawByte != null && PrikeyRawByte.length > 0);
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public minsecurity.identity.KeyParam getKeyParam() {
return KeyParam;
}
public void setKeyParam(minsecurity.identity.KeyParam keyParam) {
KeyParam = keyParam;
}
public PrivateKeyInterface getPrikey() {
return Prikey;
}
public void setPrikey(PrivateKeyInterface prikey) {
Prikey = prikey;
}
public byte[] getPrikeyRawByte() {
return PrikeyRawByte;
}
public void setPrikeyRawByte(byte[] prikeyRawByte) {
PrikeyRawByte = prikeyRawByte;
}
public PublicKeyInterface getPubkey() {
return Pubkey;
}
public void setPubkey(PublicKeyInterface pubkey) {
Pubkey = pubkey;
}
public String getPasswd() {
return Passwd;
}
public void setPasswd(String passwd) {
Passwd = passwd;
}
public Certificate getCert() {
return Cert;
}
public void setCert(Certificate cert) {
Cert = cert;
}
public boolean isDefault() {
return IsDefault;
}
public void setDefault(boolean aDefault) {
IsDefault = aDefault;
}
@Override
public String toString() {
return "Identity{" +
"Name='" + Name + '\'' +
", KeyParam.signAlgo=" + KeyParam.SignatureAlgorithm +
", KeyParam.pubAlgo=" + KeyParam.PublicKeyAlgorithm +
", Prikey=" + ByteUtils.toHexString(Prikey.getBytes()) +
", pubKey=" + ByteUtils.toHexString(Pubkey.getBytes()) +
", PrikeyRawByte=" + (PrikeyRawByte == null ? "null":ByteUtils.toHexString(PrikeyRawByte)) +
", Pubkey=" + Pubkey +
", Passwd='" + Passwd + '\'' +
", Cert=" + Cert +
", isDefault=" + IsDefault +
'}';
}
}