非对称加密 ECC算法

ECC 算法

椭圆曲线密码学Elliptic Curve Cryptography,缩写:ECC)是一种基于椭圆曲线数学的公开密钥加密算法。

ECC的主要优势是它相比RSA加密算法使用较小的密钥长度并提供相当等级的安全性。

在这里插入图片描述

java jdk未提供ecc实现

java bouncycastle实现

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

EccUtils.java

package crypto.ec;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * bouncycastle @link{https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on/1.70} 实现的ECC非对称加密实现
 */
public class EccUtils {

    private static final String ALGORITHM = "EC";

    private static final String DEFAULT_TRANSFORMATION = "ECIES";

    private static final String PROVIDER = "BC";

    static {
        Provider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        //Provider[] providers = Security.getProviders();
        //Arrays.asList(providers).stream().forEach(p -> print(p));
    }

    private static void print(Provider provider) {
        System.out.println("\n服务提供方:" + provider.getName());
        provider.getServices().forEach(service -> System.out.println(service.getType() + " : " + service.getAlgorithm()));
    }

    public static InnerKey generateKey() throws Exception {
        return generateKey(224);
    }

    /**
     * 初始化密钥
     *
     * @param keySize 192 bit, 224 bit, 256 bit
     * @return
     * @throws Exception
     */
    public static InnerKey generateKey(int keySize) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
        keyPairGenerator.initialize(keySize);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return InnerKey.builder().publicKey(keyPair.getPublic().getEncoded()).privateKey(keyPair.getPrivate().getEncoded()).build();
    }

    public static byte[] encrypt(byte[] publicKey, byte[] data) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER); // https://gitee.com/dromara/hutool/issues/I1UYNJ
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);
        PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

        Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION, PROVIDER);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey2);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(byte[] privateKey, byte[] data) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
        PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8KeySpec);

        Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORMATION, PROVIDER);
        cipher.init(Cipher.DECRYPT_MODE, privateKey2);
        return cipher.doFinal(data);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class InnerKey {
        private byte[] publicKey;
        private byte[] privateKey;
    }
}

测试代码

package crypto.ec;

import org.apache.commons.codec.binary.Base64;

public class EccUtilsTest {

    public static void main(String[] args) throws Exception {
        EccUtils.InnerKey key = EccUtils.generateKey(256);
        System.out.println("公钥:" + Base64.encodeBase64String(key.getPublicKey()));
        System.out.println("私钥:" + Base64.encodeBase64String(key.getPrivateKey()));

        byte[] bytes = EccUtils.encrypt(key.getPublicKey(), "你好中国".getBytes());
        System.out.println("密文:" + Base64.encodeBase64String(bytes));
        byte[] result = EccUtils.decrypt(key.getPrivateKey(), bytes);
        System.out.println(new String(result));
    }
}

code

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值