一、Ecc算法
椭圆加密算法(Elliptic curve cryptography,Ecc)是一种公钥加密体系,算法的基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。ECC算法属于非对称算法,在对带宽要求较高的连接中将十分有用。
Ecc算法的特点包括:
1. 安全性高
有研究表明,160位的椭圆秘钥的安全性等同于1024位的RSA的密钥安全性。可以说,黑客很难通过暴力破解的来对加密后的数据进行破解。
2. 处理速度快
- 带宽要求低
- 存储空间占用小
- 通过私钥对公钥加密的数据进行解密的时候,Ecc解密速度要比RSA和DSA的速度要快
在应用上,Ecc算法的主要应用点包括:
- 数字签名
- 使用Ecc加密对称加密算法生成的密钥,进而保证密钥可安全地在网络上进行传输
ECC作为常用的非对称加密算法,加解密宏观流程如下:
二、Ecc算法公钥、私钥生成代码
1、引入maven依赖包
<dependency>
<groupId>org.e-hoffman.crypto</groupId>
<artifactId>CryptoBouncyCastle</artifactId>
<version>${cryptoBouncyCastle.version}</version>
</dependency>
2、生成公钥、私钥代码示例-1
public class EccKeyPair {
private static final SecureRandom RANDOM = new SecureRandom();
/**
* 私钥
*/
private String privateKey;
/**
* 公钥
*/
private String publicKey;
/**
* 椭圆曲线
*/
private static final String CURVE_NAEM = "secp256k1";
public EccKeyPair() {
generateKey();
Assert.notNull(publicKey, "公钥不可为null");
Assert.notNull(privateKey, "私钥不可为null");
}
private void generateKey() {
ECKeyPairGenerator generator = new ECKeyPairGenerator();
X9ECParameters secNameCurves = SECNamedCurves.getByName(CURVE_NAEM);
ECDomainParameters domainParameters = new ECDomainParameters(secNameCurves.getCurve(), secNameCurves.getG(), secNameCurves.getN(), secNameCurves.getH());
ECKeyGenerationParameters ecKeyGenerationParameters = new ECKeyGenerationParameters(domainParameters, RANDOM);
generator.init(ecKeyGenerationParameters);
AsymmetricCipherKeyPair keyPair = generator.generateKeyPair();
// 私钥
ECPrivateKeyParameters privateKeyParameters = (ECPrivateKeyParameters) keyPair.getPrivate();
byte[] privateKeyBytes = privateKeyParameters.getD().toByteArray();
this.privateKey = Base64Util.encode2String(privateKeyBytes);
// 公钥
ECPublicKeyParameters publicKeyParameters = (ECPublicKeyParameters) keyPair.getPublic();
byte[] publicKeyBytes = publicKeyParameters.getQ().getEncoded();
this.publicKey = Base64Util.encode2String(publicKeyBytes);
}
public String getPrivateKey() {
return privateKey;
}
public String getPublicKey() {
return publicKey;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("EccKeyPair{");
sb.append("privateKey='").append(privateKey).append('\'');
sb.append(", publicKey='").append(publicKey).append('\'');
sb.append('}');
return sb.toString();
}
3、生成公钥、私钥代码示例-2
public class EccUtil{
/**
* 生成密钥对
*
* @return
*/
public static KeyPair generateKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
keyPairGenerator.initialize(KEY_SIZE, new SecureRandom());
return keyPairGenerator.generateKeyPair();
}
/**
* 获取公钥(Base64编码)
*
* @param keyPair
* @return
*/
public static String getPublicKey(KeyPair keyPair) throws Exception {
if (Objects.isNull(keyPair)) {
throw new IllegalArgumentException();
}
PublicKey publicKey = keyPair.getPublic();
byte[] publicKeyEncoded = publicKey.getEncoded();
if (Objects.isNull(publicKeyEncoded)) {
throw new Exception("公钥编码异常");
}
return new String(Base64.getEncoder().encode(publicKeyEncoded));
}
/**
* 获取私钥(Base64编码)
*
* @param keyPair
* @return
* @throws Exception
*/
public static String getPrivateKey(KeyPair keyPair) throws Exception {
if (Objects.isNull(keyPair)) {
throw new IllegalArgumentException();
}
PrivateKey privateKey = keyPair.getPrivate();
byte[] privateKeyEncoded = privateKey.getEncoded();
if (Objects.isNull(privateKeyEncoded)) {
throw new Exception("私钥编码异常");
}
return new String(Base64.getEncoder().encode(privateKeyEncoded));
}
}