椭圆算法加密,java实现

简介
椭圆加密算法(ECC)是一种公钥加密体制,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类:大素数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。

速度     ecc算法比RSA、DSA速度更快。

椭圆曲线密码学
椭圆曲线密码学(英语:Elliptic curve cryptography,缩写为ECC),一种建立公开密钥加密的演算法,基于椭圆曲线数学。椭圆曲线在密码学中的使用是在1985年由Neal Koblitz和Victor Miller分别独立提出的。

ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。

优点
 有研究表示160位的椭圆密钥与1024位的RSA密钥安全性相同。

处理速度快
在私钥的加密解密速度上,ecc算法比RSA、DSA速度更快。

存储空间占用小。

带宽要求低。

ECC:Elliptic Curves Cryptography,椭圆曲线密码编码学

ECDSA:用于数字签名,是ECC与DSA的结合,整个签名过程与DSA类似,所不一样的是签名中采取的算法为ECC,最后签名出来的值也是分为r,s。

ECDH:是基于ECC(Elliptic Curve Cryptosystems,椭圆曲线密码体制,参看ECC)的DH( Diffie-Hellman)密钥交换算法。它是密钥协商算法,而不是加解密算法。

ECDH用途:
由于通过ECDH,双方可以在不共享任何秘密的前提下协商出一个共享秘密,因此,ECDH广泛用于协议之中,通过ECDH得到对称加密密钥。如TLS中的*_ECDH_*密码套件。使用DH算法的协议,都可以升级到ECDH算法。ECDH具有ECC的高强度、短密钥长度、计算速度快等优点。

密钥交换过程:
假设密钥交换双方为Alice、Bob,其有共享曲线参数(椭圆曲线E、阶N、基点G)。

1.Alice生成随机整数a,计算A=a*G。Bob生成随机整数b,计算B=b*G。
2.Alice将A传递给Bob。A的传递可以公开,即攻击者可以获取A。由于椭圆曲线的离散对数问题是难题,所以攻击者不可以通过A、G计算出a。Bob将B传递给Alice。同理,B的传递可以公开。

3.Bob收到Alice传递的A,计算Q=b*A

4.Alice收到Bob传递的B,计算Q‘=a*B

总结:
  Alice、Bob双方即得Q=b*A=b*(a*G)=(b*a)*G=(a*b)*G=a*(b*G)=a*B=Q' (交换律和结合律),即双方得到一致的密钥Q。

java实现:

导包

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

工具类

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class ECCUtils {

    /**
     * 生成密钥对(公钥和私钥)
     *
     * @return
     * @throws Exception
     */
    public static KeyPair initKey(int keySize, String KEY_ALGORITHM) throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(keySize);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        return keyPair;
    }

    /**
     * 公钥加密
     *
     * @param data      源数据
     * @param publicKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String data, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(publicKey);
        Security.addProvider(new BouncyCastleProvider());
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        Cipher cipher = Cipher.getInstance("ECIES", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, keyFactory.generatePublic(x509KeySpec));
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));

    }

    /**
     * 私钥解密
     *
     * @param encryptedData 已加密数据
     * @param privateKey    私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String encryptedData, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("ECIES", "BC");
        cipher.init(Cipher.DECRYPT_MODE, keyFactory.generatePrivate(pkcs8KeySpec));
        return Base64.getEncoder().encodeToString(cipher.doFinal(Base64.getDecoder().decode(encryptedData)));
    }

    /**
     * 用私钥对信息生成数字签名
     *
     * @param content     已加密数据 base64
     * @param priKey      私钥(BASE64编码)
     * @param signatureAl 签名算法
     * @return
     * @throws Exception
     */
    public static String sign(String content, String priKey, String signatureAl) throws Exception {
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(priKey));
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        ECPrivateKey privateK = (ECPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        Signature sign = Signature.getInstance(signatureAl);//"SHA256withECDSA/"
        sign.initSign(privateK);
        sign.update(Base64.getDecoder().decode(content));
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    public static void main(String[] args) {
        try {
            //初始化获取公钥和私钥
            KeyPair keypair = initKey(256, "EC");

            PublicKey publicKey = keypair.getPublic();
            PrivateKey privateKey = keypair.getPrivate();

            System.out.println("私钥原:" + privateKey);
            System.out.println("公钥原:" + publicKey);

//            String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKey.getEncoded());
//            String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKey.getEncoded());

            //生成固定公钥私钥
            String publicKeyBase64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvVlOVXJQe6yyLlCSCWQr246yay4Hl9qfB3C5S9al9t6cNzP3lwjJIRGzFmGywspn0OwiMJWmFV7daLhzCx79kQ==";
            String privateKeyBase64 = "MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCDyvdnfevbZyiWDWOmwRp5hLDftlNWHzdD5YkiQW6hR6g==";

            System.out.println("公钥:" + publicKeyBase64);
            System.out.println("-----");
            System.out.println("私钥:" + privateKeyBase64);

            String con = "这是一条测试加密的数据,哈哈哈哈";
            System.out.println("加密之前:" + con);
            //加密
            String content = encryptByPublicKey(con, publicKeyBase64);
            //解密
            String contentDe = decryptByPrivateKey(content, privateKeyBase64);
            //解密之后
            String deStr = new String(Base64.getDecoder().decode(contentDe));
            System.out.println("解密之后:" + deStr);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

测试结果

 

椭圆曲线加密(Elliptic Curve Cryptography,ECC)是一种非对称加密算法,其中的加密和解密操作基于椭圆曲线上的点运算。在Java中,可以使用Bouncy Castle库来实现椭圆曲线加密解密。 以下是一个简单的示例代码,演示了如何使用Bouncy Castle库在Java实现椭圆曲线加密解密: ```java import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; public class ECCExample { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // 生成密钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC"); ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256k1"); // 指定椭圆曲线参数 keyPairGenerator.initialize(ecGenParameterSpec); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 获取公钥和私钥 ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic(); ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate(); // 加密 String plaintext = "Hello, ECC!"; Cipher encryptCipher = Cipher.getInstance("ECIES", "BC"); encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] ciphertext = encryptCipher.doFinal(plaintext.getBytes()); // 解密 Cipher decryptCipher = Cipher.getInstance("ECIES", "BC"); decryptCipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedText = decryptCipher.doFinal(ciphertext); System.out.println("Plaintext: " + plaintext); System.out.println("Decrypted Text: " + new String(decryptedText)); } } ``` 在这个示例中,我们首先添加了Bouncy Castle提供的加密算法提供者。然后,我们使用`KeyPairGenerator`生成了一个椭圆曲线密钥对,指定了椭圆曲线参数为"secp256k1"。接下来,我们获取公钥和私钥,并使用公钥进行加密,私钥进行解密。最后,我们打印出明文和解密后的文本。 请注意,这只是一个简单的示例代码,实际使用中需要考虑更多的安全性和异常处理。 希望这能帮助到你!如果还有其他问题,请随时提问。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值