JAVA——RSA加密【X509EncodedKeySpec、PKCS8EncodedKeySpec、RSAPublicKeySpec、RSAPrivateKeySpec】

basic concepts

RSA encryption algorithm : SA encryption algorithm is an asymmetric encryption algorithm. In public-key encryption and electronic commerce RSA is widely used. RSA 1977 by the Ronald Rivest (Ron Rivest), Adi Shamir (Adi Shamir) and Leonard Adleman (Leonard Adleman) presented together. At that time the three of them are working at MIT. RSA is the three of them last names beginning with the letter composed pieces together.

RSA public key encryption algorithm is the most influential, the algorithm is based on a very simple arithmetical fact: multiplying two large prime numbers is very easy, but then want to factorization of their product is extremely difficult, so product may be disclosed as the encryption key, i.e. the public key, the private key two large prime the synthesis of arrays. The public key is available for the release of any person to use, the private key was all his, for decryption purposes.

Who owns the private key to decrypt, and will be calculated generated by private-public key encryption to release. Using the public key encryption are encrypted, and transmits the ciphertext to the decryption by decryption by the decryption with the private key to decode the ciphertext to plaintext.

API

https://docs.oracle.com/javase/7/docs/api/index.html 

X509EncodedKeySpec

  • This class represents the ASN.1 encoding a public key, according to the ASN.1 type SubjectPublicKeyInfois encoded. SubjectPublicKeyInfoX.509 standard syntax is defined as follows:
      SubjectPublicKeyInfo ::= SEQUENCE {
       algorithm AlgorithmIdentifier,
       subjectPublicKey BIT STRING } 

 

Construction method:

X509EncodedKeySpec(byte[] encodedKey)

Given encoded key to create a new X509EncodedKeySpec use.

 

parameter

encodedKey- assuming the encoding key according to the X.509 standard. Copy the contents of the array to prevent subsequent modifications.

abnormal

NullPointerException- if encodedKeyempty.

PKCS8EncodedKeySpec

  • Representative of such private key ASN.1 encoding, according to the type of ASN.1 PrivateKeyInfoencoding. PrivateKeyInfoSyntax defined in the standard PKCS # 8 as follows:
      PrivateKeyInfo ::= SEQUENCE {
       version Version,
       privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
       privateKey PrivateKey,
       attributes [0] IMPLICIT Attributes OPTIONAL }
    
     Version ::= INTEGER
    
     PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
    
     PrivateKey ::= OCTET STRING
    
     Attributes ::= SET OF Attribute 

Construction method:

PKCS8EncodedKeySpec(byte[] encodedKey)

With the given encoded key to create a new PKCS8EncodedKeySpec.

RSAPrivateKeySpec

  • This class specifies an RSA private key.

Construction method:

RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent)

Create a new RSAPrivateKeySpec.

parameter

modulus - Modulus

privateExponent - private exponent

RSAPublicKeySpec

  • This class specifies an RSA public key.

Construction method:

RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent)

Create a new RSAPublicKeySpec.

parameter

modulus - Modulus

publicExponent - Public Index

DEMO 

package cn.aizichan.utils.digest;
 
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
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 java.util.HashMap;
import java.util.Map;
 
import javax.crypto.Cipher;
 
public class RSACoder {
	//非对称密钥算法  
    public static final String KEY_ALGORITHM="RSA";  
    /** 
     * 密钥长度,DH算法的默认密钥长度是1024 
     * 密钥长度必须是64的倍数,在512到65536位之间 
     * */  
    private static final int KEY_SIZE=512;  
    //公钥  
    private static final String PUBLIC_KEY="xiaoxiaorenzhe";  
      
    //私钥  
    private static final String PRIVATE_KEY="dadapangzi";  
    
    /** 
     * 初始化密钥对 
     * @return Map 甲方密钥的Map 
     * */  
    public static Map<String,Object> initKey() throws Exception{  
        //实例化密钥生成器  
        KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(KEY_ALGORITHM);  
        //初始化密钥生成器  
        keyPairGenerator.initialize(KEY_SIZE);  
        //生成密钥对  
        KeyPair keyPair=keyPairGenerator.generateKeyPair(); 
        //甲方公钥  
        RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();  
        System.out.println("系数:"+publicKey.getModulus()+"  加密指数:"+publicKey.getPublicExponent());
        //甲方私钥  
        RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate(); 
        System.out.println("系数:"+privateKey.getModulus()+"解密指数:"+privateKey.getPrivateExponent());
        //将密钥存储在map中  
        Map<String,Object> keyMap=new HashMap<String,Object>();  
        keyMap.put(PUBLIC_KEY, publicKey);  
        keyMap.put(PRIVATE_KEY, privateKey);  
        return keyMap;  
          
    }  
    
    /** 
     * 私钥加密 
     * @param data待加密数据 
     * @param key 密钥 
     * @return byte[] 加密数据 
     * */  
    public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{  
          
        //取得私钥  
        PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);  
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);  
        //生成私钥  
        PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);  
        //数据加密  
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);  
        return cipher.doFinal(data);  
    }  
    
    /** 
     * 公钥加密 
     * @param data待加密数据 
     * @param key 密钥 
     * @return byte[] 加密数据 
     * */  
    public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{  
          
        //实例化密钥工厂  
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);  
        //初始化公钥  
        //密钥材料转换  
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);  
        //产生公钥  
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);  
          
        //数据加密  
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);  
        return cipher.doFinal(data);  
    }  
    /** 
     * 私钥解密 
     * @param data 待解密数据 
     * @param key 密钥 
     * @return byte[] 解密数据 
     * */  
    public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{  
        //取得私钥  
        PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);  
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);  
        //生成私钥  
        PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);  
        //数据解密  
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.DECRYPT_MODE, privateKey);  
        return cipher.doFinal(data);  
    }  
    
    /** 
     * 公钥解密 
     * @param data 待解密数据 
     * @param key 密钥 
     * @return byte[] 解密数据 
     * */  
    public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{  
          
        //实例化密钥工厂  
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);  
        //初始化公钥  
        //密钥材料转换  
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);  
        //产生公钥  
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);  
        //数据解密  
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.DECRYPT_MODE, pubKey);  
        return cipher.doFinal(data);  
    }  
    
    /** 
     * 取得私钥 
     * @param keyMap 密钥map 
     * @return byte[] 私钥 
     * */  
    public static byte[] getPrivateKey(Map<String,Object> keyMap){  
        Key key=(Key)keyMap.get(PRIVATE_KEY);  
        return key.getEncoded();  
    }  
    /** 
     * 取得公钥 
     * @param keyMap 密钥map 
     * @return byte[] 公钥 
     * */  
    public static byte[] getPublicKey(Map<String,Object> keyMap) throws Exception{  
        Key key=(Key) keyMap.get(PUBLIC_KEY); 
        return key.getEncoded();  
    }  
    /** 
     * @param args 
     * @throws Exception  
     */  
    public static void main(String[] args) throws Exception {  
        //初始化密钥  
        //生成密钥对  
        Map<String,Object> keyMap=RSACoder.initKey();  
        //公钥  
        byte[] publicKey=RSACoder.getPublicKey(keyMap);
        //byte[] publicKey = b;
        //私钥  
        byte[] privateKey=RSACoder.getPrivateKey(keyMap);  
        System.out.println("公钥:"+Base64.encode(publicKey));       
        System.out.println("私钥:"+Base64.encode(privateKey));  
          
        System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输=============");  
        String str="aattaggcctegthththfef/aat.mp4";  
        System.out.println("===========甲方向乙方发送加密数据==============");  
        System.out.println("原文:"+str);  
        //甲方进行数据的加密  
        byte[] code1=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);
        System.out.println("甲方 使用乙方公钥加密后的数据:"+Base64.encode(code1));  
        System.out.println("===========乙方使用甲方提供的公钥对数据进行解密==============");  
        //乙方进行数据的解密  
        //byte[] decode1=RSACoder.decryptByPublicKey(code1, publicKey);  
        byte[] decode1=RSACoder.decryptByPrivateKey(code1, privateKey);  
        System.out.println("乙方解密后的数据:"+new String(decode1)+"");  
          
        System.out.println("===========反向进行操作,乙方向甲方发送数据==============");  
          
        str="乙方向甲方发送数据RSA算法";  
          
        System.out.println("原文:"+str);  
          
        //乙方使用公钥对数据进行加密  
        byte[] code2=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);  
        System.out.println("===========乙方使用公钥对数据进行加密==============");  
        System.out.println("加密后的数据:"+Base64.encode(code2));  
          
        System.out.println("=============乙方将数据传送给甲方======================");  
        System.out.println("===========甲方使用私钥对数据进行解密==============");  
          
        //甲方使用私钥对数据进行解密  
        byte[] decode2=RSACoder.decryptByPrivateKey(code2, privateKey);  
          
        System.out.println("甲方解密后的数据:"+new String(decode2)); 
        
        
    }  
}

Reference article

https://www.iteye.com/topic/1148471

https://www.jianshu.com/p/40a1be871bee

https://blog.csdn.net/tabactivity/article/details/49685319

发布了1354 篇原创文章 · 获赞 228 · 访问量 29万+

Guess you like

Origin blog.csdn.net/weixin_43272781/article/details/103995547
Recommended