天天看點

java web 非對稱加密。RSA算法加密。首先解釋一下 web 中的流程:非對稱性加密:踩過的坑:

首先解釋一下 web 中的流程:

前端會有專門的方法利用對應的公/私鑰 對需要加密的内容進行加密,背景得到加密後的内容後 利用對應的公/私鑰 進行解密 或相應操作。

非對稱性加密:

解決浏覽器傳輸過程中 明文傳輸易被竊取的情況。

算法生成兩個密匙 公鑰 -私鑰; 公鑰是的可以對外公開的,私鑰是自己保留的。

避免頻繁交換秘鑰帶來的不便。

RSA算法一次生成 一對秘鑰,用其中一個加密 則可以使用另一個解密。

(PS:也就是說會有2種情況,1.公鑰加密-私鑰解密 , 2私鑰加密-公鑰解密)

踩過的坑:

每次生成的一對秘鑰 頭尾一緻,身子不是一緻的,請注意。

正常的網上給出的RSA加密例子都是從頭到尾 加密解密過一遍,但是! 你要是自己嘗試分離的話,請注意 :

  • 1 生成秘鑰的語句執行一次就好。保留住你的公私鑰。然後直接去愉快的嘗試,不要反複生成公私密鑰 拿不比對秘鑰去解密文,必報錯javax.crypto.BadPaddingException: Decryption error。
  • 2 類型轉換,你儲存的是 String類型的key 普通分離出來的方法需要傳入RSAPublicKey/RSAPrivateKey類型的參數,然後去嘗試類型轉換,頭疼。
  • 3 前端傳到背景的密文 “+” 号可能被替換成 “ 空格”,

    謹以此文紀念我逝去的一個早上。

常見的CSDN上的加密解密不分離的例子:來自https://blog.csdn.net/jijianshuai/article/details/80582187

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

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

/**
 * 非對稱加密 唯一廣泛接受并實作 資料加密&數字簽名 公鑰加密、私鑰解密 私鑰加密、公鑰解密
 * 
 * @author jjs
 *
 */
public class RSADemo {

    private static String src = "infcn";

    private static RSAPublicKey rsaPublicKey;
    private static RSAPrivateKey rsaPrivateKey;

    static {
        // 1、初始化密鑰
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);// 64的整倍數
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            System.out.println("Public Key : " + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            System.out.println("Private Key : " + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * 公鑰加密,私鑰解密
     * @author jijs
     */
    public static void pubEn2PriDe() {
        //公鑰加密
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("公鑰加密,私鑰解密 --加密: " + Base64.encodeBase64String(result));

        //私鑰解密
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
        keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        result = cipher.doFinal(result);
        System.out.println("公鑰加密,私鑰解密 --解密: " + new String(result));
    }


    /**
     * 私鑰加密,公鑰解密
     * @author jijs
     */
    public static void priEn2PubDe() {

        //私鑰加密
        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(src.getBytes());
        System.out.println("私鑰加密,公鑰解密 --加密 : " + Base64.encodeBase64String(result));

        //公鑰解密
        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);
        System.out.println("私鑰加密,公鑰解密   --解密: " + new String(result));
    }

    public static void main(String[] args) {
        pubEn2PriDe();  //公鑰加密,私鑰解密
        priEn2PubDe();  //私鑰加密,公鑰解密
    }
}
           

想快速使用的話建議使用别人封裝好的。

https://www.jianshu.com/p/bdf59b6a01ab

繼續閱讀