本节讲的SM2的实现,这个其实是可以参照RSA来写,都是非对称加密。
我们通过KeyPairGenerator.getInstance("SM2").generateKeyPair();来获取密钥对,最后调用的就是KeyPairGenSpi的generateKeyPair(),仿照RSA中的KeyPairGeneratorSpi来写,
package org.gk.gm.SM2.spi;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi.EC;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.gk.gm.SM2.util.ECUtil;
import org.gk.gm.provider.SMProvider;
public class KeyPairGenSpi extends EC {
public KeyPairGenSpi() {
try {
X9ECParameters x9 = ECUtil.getNamedCurveByName("SM2");
ECParameterSpec parameterSpec = new ECParameterSpec(x9.getCurve(), x9.getG(), x9.getN());
super.initialize(parameterSpec, (SecureRandom)null);
} catch (InvalidAlgorithmParameterException var2) {
var2.printStackTrace();
}
}
public KeyPair generateKeyPair() {
KeyPair keyPair = super.generateKeyPair();
try {
SM2PrivateKey e = new SM2PrivateKey((ECPrivateKey)keyPair.getPrivate(), SMProvider.CONFIGURATION);
SM2PublicKey publicKey = new SM2PublicKey((ECPublicKey)keyPair.getPublic(), SMProvider.CONFIGURATION);
return new KeyPair(publicKey, e);
} catch (InvalidKeyException var4) {
return null;
}
}
public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
super.initialize((AlgorithmParameterSpec)null, (SecureRandom)null);
}
public void initialize(int keySize) {
try {
super.initialize((AlgorithmParameterSpec)null, (SecureRandom)null);
} catch (InvalidAlgorithmParameterException var3) {
;
}
}
public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
super.initialize((AlgorithmParameterSpec)null, random);
}
public void initialize(int keySize, SecureRandom random) {
try {
super.initialize((AlgorithmParameterSpec)null, random);
} catch (InvalidAlgorithmParameterException var4) {
;
}
}
}
我们这里继承EC(EC也是继承KeyPairGenerator的),其中构造方法就是对SM2进行初始化,SM2PublicKey,SM2PrivateKey这个都是自定义的,这个可以随个人的爱好,只是加解密的时候,对应的变一下就可以了,这里公钥genEncode返回的是512bit(128byte),私钥256bit(64byte)。
好了,再看加密,加密CipherSpi这个类跟RSA的差不多。
public class CipherSpi extends BaseCipherSpi {
private int opMode;
private AsymmetricKeyParameter keyParam = null;
private SM2Cipher sm2Cipher = null;
private ECPoint c1 = null;
private ByteArrayOutputStream bout = null;
public CipherSpi() {
}
protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
if(opmode != 1 && opmode != 2) {
throw new InvalidKeyException("Only supports ENCRYPT_MODE|DECRYPT_MODE.");
} else if(key == null || !(key instanceof ECPublicKey) && !(key instanceof ECPrivateKey)) {
throw new InvalidKeyException("No useful Key.");
} else if(opmode == 2 && key instanceof ECPublicKey) {
throw new InvalidKeyException("DECRYPT_MODE needs a Private Key.");
} else {
if(this.sm2Cipher == null) {
this.sm2Cipher = new SM2Cipher();
}
this.keyParam = key instanceof ECPublicKey?ECUtil.generatePublicKeyParameter((ECPublicKey)key):ECUtil.generatePrivateKeyParameter((ECPrivateKey)key);
if(opmode == 1) {
ECPoint q = null;
if(