非对称加密解密:DH算法+RSA算法+ElGamal算法[小戴某]

DH简单效果图

非对称加密算法是一种基于密钥的保密方法,需要公开密钥和私有密钥,在文件加密、尤其是网银中应用广泛。


RSA

DH密钥交换算法

  • Diffie-Helman
  • 对称加密带来的困扰
  • 构建本地密钥
  • 对称


    DH密钥说明
DH算法的步骤
  • 初始化发送方密钥

    1. KeyPairGenerator [ 生成KeyPair的类 ]
      (可以指定算法名称或者来指定加密的提供方)


      KeyPairGenerator的生成方法
    2. KeyPair [ 获取常用的密钥载体/密钥对.] [ 通常有两个信息,一个公钥(PublicKey)一个私钥(PrivateKey) ]
    3. PublicKey
  • 初始化接收方密钥

    1. KeyFactory [ 密钥工厂/生成密钥 ]
      · generatePublic() 生成公钥
      · generatePrivate() 生成私钥
    2. X509EncodedKeySpec [ 根据ASN.1标准进行密钥编码 ]
    3. DHPublicKey [ PublicKey某种具体的形式 ]
    4. DHParameterSpec [ 随同DH算法来使用的参数集合 ]
    5. KeyPairGenerator [ 生成KeyPair ]
    6. PrivateKey
  • 密钥构建

    1. KeyAgreement [ 提供密钥一致性的协议的功能 ]
    2. SecreatKey [ 生成一个分组的秘密密钥,提供了类型安全的操作 ]
    3. KeyFactory
    4. X509EncodedKeySpec
    5. Publickey
  • 加密/解密

    1. Cipher [ JCE框架核心内容 ]


      创建Cipher对象
整个流程图

撸代码咯~~~~~~~~~~~

 private void jdkDH() {
        try {

            // 1.初始化发送方密钥
            KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            sendKeyPairGenerator.initialize(512);//设置长度
            KeyPair sendKeyPair = sendKeyPairGenerator.generateKeyPair();// 生成密钥对
            byte[] sendPublicKeyEncoded = sendKeyPair.getPublic().getEncoded();// 获取Byte数组形式 发送方的公钥 ---> 发送给接收方(网络、文件、U盘拷贝[需要序列化])

            // 2.初始化接收方的密钥
            KeyFactory receiveKeyFactory = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(sendPublicKeyEncoded);
            PublicKey receivePublicKey = receiveKeyFactory.generatePublic(x509EncodedKeySpec); // 接收方公钥
            DHParameterSpec dhParameterSpec = ((DHPublicKey) receivePublicKey).getParams();
            KeyPairGenerator receiveKeyPairGenerator = KeyPairGenerator.getInstance("DH");
            receiveKeyPairGenerator.initialize(dhParameterSpec);
            KeyPair receiveKeyPair = receiveKeyPairGenerator.generateKeyPair();
            PrivateKey receivePrivate = receiveKeyPair.getPrivate();
            byte[] receivePublicKeyEncoded = receiveKeyPair.getPublic().getEncoded();

            // 3.密钥构建
            KeyAgreement receiveKeyAgreement = KeyAgreement.getInstance("DH");
            receiveKeyAgreement.init(receivePrivate);
            receiveKeyAgreement.doPhase(receivePublicKey, true);
            SecretKey receiveDesKey = receiveKeyAgreement.generateSecret("DES"); // 生成本地密钥

            KeyFactory sendKeyFactory = KeyFactory.getInstance("DH");
            x509EncodedKeySpec = new X509EncodedKeySpec(receivePublicKeyEncoded);
            PublicKey sendPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec);
            PrivateKey sendPrivateKey = sendKeyPair.getPrivate();
            KeyAgreement sendKeyAgreement = KeyAgreement.getInstance("DH");
            sendKeyAgreement.init(sendPrivateKey);
            sendKeyAgreement.doPhase(sendPublicKey, true);

            // 生成发送方的本地密钥
            SecretKey sendDesKey = sendKeyAgreement.generateSecret("DES");
            if (receiveDesKey.equals(sendDesKey)) {
                Log.i("DH----->", "jdkDH: " + "双方密钥相同");
            }

            // 4.加密
            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("DES");

            cipher.init(Cipher.ENCRYPT_MODE,sendDesKey); // 加密模式
            byte[] result = cipher.doFinal(srcDH.getBytes()); //加密结果
            Log.i("DH----->加密结果", "result: "+ Arrays.toString(result));

            // 5.解密
            cipher.init(Cipher.DECRYPT_MODE,receiveDesKey); // 解密模式
            result = cipher.doFinal(result); //加密结果
            Log.i("DH----->解密结果", "result: "+ new String(result)); // 解密的内容是加密时生成的结果

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

RSA非对称加密算法

  • 基于因子分解
RSA的特点
RSA密钥基本信息
RSA思路图
RSA思路图
代码实现
private static void jdkRSA() {
        try {

            //1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512); // 设置长度 最大值 6536
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); // RSA公钥
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); // RSA私钥
            Log.i("RSA----->", "RSA公钥: "+rsaPublicKey);
            Log.i("RSA----->", "RSA私钥: "+rsaPrivateKey);

            //2.私钥加密、公钥解密 --- 加密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 最终使用的私钥
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,privateKey); // 加密模式
            byte[] result = cipher.doFinal(srcRSA.getBytes());
            Log.i("RSA----->私钥加密、公钥解密", "-------加密: "+ Arrays.toString(result));

            //3.私钥加密、公钥解密 --- 解密
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,publicKey);
            result = cipher.doFinal(result);
            Log.i("RSA----->私钥加密、公钥解密", "-------解密: "+  new String(result));

            // 4.公钥加密、私钥解密 --- 加密
            x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,publicKey); // 加密
            result = cipher.doFinal(srcRSA.getBytes());
            Log.i("RSA----->公钥加密、私钥解密", "-------加密: "+ Arrays.toString(result));

            // 5.公钥加密、私钥解密 --- 解密
            pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,privateKey);
            result = cipher.doFinal(result);
            Log.i("RSA----->公钥加密、私钥解密", "-------解密: "+ new String(result));


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

ElGamal算法

  • 基于离散对数
  • 只提供公钥加密算法
  • JDK里没有提供实现,在BC里(Bouncy Castle)实现


    ElGamal密钥基本信息
ElGamal思路图

代码编写与RSA相似我们就不去演示了

1.png

你可能感兴趣的:(非对称加密解密:DH算法+RSA算法+ElGamal算法[小戴某])