## 1 简介

- 非对称加密算法需要两个密钥：`公开密钥(publickey)` 和`私有密钥(privatekey)`
- 如果用`公开密钥`对数据进行`加密`，只有用`对应的私有密钥`才能`解密`。
- 如果用`私有密钥`对数据进行`加密`，只有用`对应的公开密钥`才能`解密`

常见算法

* RSA
* ECC

## 2 RSA

```java
public class RSADemo {
    public static void main(String[] args) throws Exception {

        //加密算法
        String algorithm = "RSA";
        //创建密钥对生成器对象
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        //生成密钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //生成私钥
        PrivateKey privateKey = keyPair.getPrivate();
        //生成公钥
        PublicKey publicKey = keyPair.getPublic();
        //获取私钥字节数组
        byte[] privateKeyEncoded = privateKey.getEncoded();
        //获取公钥字节数组
        byte[] publicKeyEncoded = publicKey.getEncoded();
        //对公私钥进行base64编码
        String privateKeyString = Base64.encode(privateKeyEncoded);
        String publicKeyString = Base64.encode(publicKeyEncoded);
        //打印私钥
        //System.out.println(privateKeyString);
        //打印公钥
        //System.out.println(publicKeyString);

        //privateEncode(algorithm, privateKey, publicKey);

        publicEncode(algorithm, privateKey, publicKey);

    }

    //私钥加密 公钥解密
    private static void privateEncode(String algorithm, PrivateKey privateKey, PublicKey publicKey) {
        try {
            String input = "Hello World";
            //创建加密对象
            //参数表示加密算法
            Cipher cipher = Cipher.getInstance(algorithm);
            //初始化加密
            //第一个参数:加密的模式
            //第二个参数：使用私钥进行加密
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            // 私钥加密
            byte[] bytes = cipher.doFinal(input.getBytes());
            System.out.println(Base64.encode(bytes));
            //公钥解密
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            //对密文进行解密，不需要使用base64，因为原文不会乱码
            byte[] bytes1 = cipher.doFinal(bytes);
            System.out.println(new String(bytes1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //私钥加密 公钥解密
    private static void publicEncode(String algorithm, PrivateKey privateKey, PublicKey publicKey) {
        try {
            String input = "Hello World";
            // 创建加密对象
            // 参数表示加密算法
            Cipher cipher = Cipher.getInstance(algorithm);
            // 初始化加密
            // 第一个参数:加密的模式
            // 第二个参数：使用私钥进行加密
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            //公钥加密
            byte[] bytes = cipher.doFinal(input.getBytes());
            System.out.println(Base64.encode(bytes));
            //私钥解密
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //对密文进行解密，不需要使用base64，因为原文不会乱码
            byte[] bytes1 = cipher.doFinal(bytes);
            System.out.println(new String(bytes1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
```

## 3  ECC

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

优点:

- 安全性高，有研究表示160位的椭圆密钥与1024位的 RSA 密钥安全性相同。
- 处理速度快，在私钥的加密解密速度上，ECC 算法比 RSA、DSA 速度更快，存储空间占用小，带宽要求低。 