• sslopen RSA加解密


    一、  原理概念

    OpenSSL定义:

    OpenSSL是为网络通信提供安全及数据完整性的一种安全协议,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。

    OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。
      作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。

    功能:
      基本功能
      OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。
      作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
      辅助功能
      BIO机制是OpenSSL提供的一种高层IO接口,该接口封装了几乎所有类型的IO接口,如内存访问、文件访问以及Socket等。这使得代码的重用性大幅度提高,OpenSSL提供API的复杂性也降低了很多。
      OpenSSL对于随机数的生成和管理也提供了一整套的解决方法和支持API函数。随机数的好坏是决定一个密钥是否安全的重要前提。
      OpenSSL还提供了其它的一些辅助功能,如从口令生成密钥的API,证书签发和管理中的配置文件机制等等。如果你有足够的耐心,将会在深入使用OpenSSL的过程慢慢发现很多这样的小功能,让你不断有新的惊喜。

    1.对称加密:

    (1)甲方选择某一种加密规则,对信息进行加密;

    (2)乙方使用同一种规则,对信息进行解密。

    这种加密模式有一个最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递密钥,就成了最头疼的问题

    2.非对称加密:

    (1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

    (2)甲方获取乙方的公钥,然后用它对信息加密。

    (3)乙方得到加密后的信息,用私钥解密。

    如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。

    公钥用于加密,私钥用于解密

    二、  密钥生成步骤

    RSA加密有如下几个步骤. 
    1. 生成公钥与私钥 
    2. 用公钥对需要加密的字符串等进行加密 
    3. 在需要解密的地方,用私钥进行解密 

    三、  流程及命令

    1. 首先使用OpenSSL生成私钥:openssl genrsa –out rsa_private_key.pem 1024
    2. 根据生成的私钥生成公钥:
    • openssl rsa –in rsa_private_key.pem -out rsa_public_key.pem –pubout writing RSA key
    1. 这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
    • openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem –nocrypt

    注意:命令中指明了输入私钥文件为rsa_private_key.pem,输出私钥文件为pkcs8_rsa_private_key.pem,不采用任何二次加密(-nocrypt)

    至此,可用的密钥对已经生成好了,私钥使用pkcs8_rsa_private_key.pem,公钥采用rsa_public_key.pem。

    四、  Java

    未进行抽出方法的代码:

      1 package jdk_RSA;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.security.KeyFactory;
      5 import java.security.KeyPair;
      6 import java.security.KeyPairGenerator;
      7 import java.security.PrivateKey;
      8 import java.security.PublicKey;
      9 import java.security.interfaces.RSAPrivateKey;
     10 import java.security.interfaces.RSAPublicKey;
     11 import java.security.spec.PKCS8EncodedKeySpec;
     12 import java.security.spec.X509EncodedKeySpec;
     13 import java.util.Base64;
     14 
     15 import javax.crypto.Cipher;
     16 
     17 public class JdkRsa {
     18 //特别注意:RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行。
     19     public static void main(String[] args) {
     20         String str = "hello world!";
     21         System.out.println(str.length());
     22 //        初始化密钥
     23         PublicKey keyPublic = null;
     24         PrivateKey keyPrivate = null;
     25         byte[] prikey = null;
     26         byte[] pubkey = null;
     27         try {
     28             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
     29             keyPairGenerator.initialize(1024);
     30             KeyPair keyPair = keyPairGenerator.generateKeyPair();
     31             keyPublic = keyPair.getPublic();
     32             keyPrivate = keyPair.getPrivate();
     33             pubkey = keyPublic.getEncoded();
     34             prikey = keyPrivate.getEncoded();
     35             System.out.println("keyPublic:"+Base64.getEncoder().encodeToString(pubkey));
     36             System.out.println("keyPrivate:"+Base64.getEncoder().encodeToString(prikey));
     37         } catch (Exception e) {
     38             e.printStackTrace();
     39         }
     40 //        此时的私密还不能用,需要通过PKCS8转换为RSAPrivateKey
     41         RSAPrivateKey privateKey = null;
     42         try {
     43             KeyFactory factory = KeyFactory.getInstance("RSA");
     44             PKCS8EncodedKeySpec pkcs8PrivateKey = new PKCS8EncodedKeySpec(prikey);
     45             privateKey = (RSAPrivateKey) factory.generatePrivate(pkcs8PrivateKey);
     46             System.out.println("转化为RSAPrivateKey的值:"+Base64.getEncoder().encodeToString(privateKey.getEncoded()));
     47         } catch (Exception e) {
     48             // TODO Auto-generated catch block
     49             e.printStackTrace();
     50         }
     51         
     52 //        通过x509转换公钥为RSAPublicKey
     53         RSAPublicKey publicKey = null;
     54         try {
     55             KeyFactory factory = KeyFactory.getInstance("RSA");
     56             X509EncodedKeySpec x509PublicKey = new X509EncodedKeySpec(pubkey);
     57             publicKey = (RSAPublicKey) factory.generatePublic(x509PublicKey);
     58             System.out.println("转化为RSAPublicKey的值:"+Base64.getEncoder().encodeToString(privateKey.getEncoded()));
     59         } catch (Exception e) {
     60             // TODO Auto-generated catch block
     61             e.printStackTrace();
     62         }
     63 //        通过Cipher对象进行加密——————公钥加密
     64         String result = null;
     65         try {
     66             Cipher cipher = Cipher.getInstance("RSA");
     67             cipher.init(Cipher.ENCRYPT_MODE, publicKey);
     68             byte[] encodes = cipher.doFinal(str.getBytes());
     69             result = Base64.getUrlEncoder().encodeToString(encodes);
     70             System.out.println("公钥加密后的值:"+Base64.getUrlEncoder().encodeToString(encodes));
     71         } catch (Exception e) {
     72             // TODO Auto-generated catch block
     73             e.printStackTrace();
     74         } 
     75     
     76 //    通过Cipher对象进行加密—————私钥解密
     77     try {
     78 //        注意:这里是用base64解密后的字节数组
     79         byte[] decoderData = Base64.getUrlDecoder().decode(result.getBytes());
     80         Cipher cipher = Cipher.getInstance("RSA");
     81         cipher.init(Cipher.DECRYPT_MODE, privateKey);
     82         System.out.println("要解密长度:"+result.getBytes().length);
     83          int inputLen = decoderData.length;        
     84          ByteArrayOutputStream out = new ByteArrayOutputStream();        
     85          int offSet = 0;        
     86          byte[] cache;        
     87          int i = 0;        
     88          // 对数据分段解密        
     89          while (inputLen - offSet > 0) {
     90              if (inputLen - offSet > 128) {
     91                  cache = cipher.doFinal(decoderData, offSet, 128);
     92                  } else {
     93                      cache = cipher.doFinal(decoderData, offSet, inputLen - offSet);
     94                      }            
     95              out.write(cache, 0, cache.length);
     96              i++;
     97              offSet = i * 128;
     98              }
     99          byte[] decryptedData = out.toByteArray();
    100          out.close();
    101         System.out.println(Base64.getUrlEncoder().encodeToString(decryptedData).length());
    102         System.out.println("私钥解密后的值:"+new String(decryptedData));
    103     } catch (Exception e) {
    104         // TODO Auto-generated catch block
    105         e.printStackTrace();
    106     } 
    107 }
    108 }

    运行结果:

    1 12
    2 keyPublic:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqfHs1bBZgzgkCnKlxWEg1QLZfB+mIOH7TJ2Euew4t5gXzBDTSqXh36EPC2AzJqPRH6Eh6lcXWvRk9SV0jHuuq+yD3GxxV3sqdozYoRJIOCgmHWoXIbIqBPbefbbnNu3TeicAlZuytobit3bLSo8MZhS1tlv3Hfju/ZDiRWzGS+wIDAQAB
    3 keyPrivate:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKp8ezVsFmDOCQKcqXFYSDVAtl8H6Yg4ftMnYS57Di3mBfMENNKpeHfoQ8LYDMmo9EfoSHqVxda9GT1JXSMe66r7IPcbHFXeyp2jNihEkg4KCYdahchsioE9t59tuc27dN6JwCVm7K2huK3dstKjwxmFLW2W/cd+O79kOJFbMZL7AgMBAAECgYArIs/x1mVbHQZ+mLDuss2iW7tJFDFsfA7q0j3uisgtqNO8h0XuP17xx9zNQekKZStZvlYIXjjuem4WaaedKUerUjJa6mktj5+lhRCbqnFjRk6Jw0QJlMAyE3AuRkauKJl121vHD+EzcSiWtT2LE9AsKLlTdAzsZ2RKvaYfaXBsYQJBAPZd5uMtP4FhHLU1wQr08KqSr8H0h1m8V05UFuslR/wZ5ACX/5Eoo7rqGDGuGY3B+4zZE1ZiCoyT1oKLLh+N/okCQQCxJwaC5sgsHTB0IO+nVXQ0DeQC8PWZJ2qBF7wo9faNP4Wne8llH3m7ZMWQiL9dJ/3QOnmaHVI6i5/b1AdxXgRjAkA2TTovxnBh5vK56jAzZwuIvS4qFOikWcPwis5GZAA6y8Yab2YwK4HzF9ffU11khmYYhFwjxRZIJ+m2+lBfOh/pAkEAg0tlLAdXPDq1+puegup2oU3aO8PSgpwP93Vb4w/Il48Iw8Se0u+tDRH2ytRO4AAPwRBVp78rfnCVHhvbGE6R+QJABLGkGvDaAe7LCIwjLweu+Z5jT6qCyLSOp/PcZkdQMXiRW4X8hZlZvl7+zW3lCcTUSq49NlWbN/mVSFGK7Dznwg==
    4 转化为RSAPrivateKey的值:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKp8ezVsFmDOCQKcqXFYSDVAtl8H6Yg4ftMnYS57Di3mBfMENNKpeHfoQ8LYDMmo9EfoSHqVxda9GT1JXSMe66r7IPcbHFXeyp2jNihEkg4KCYdahchsioE9t59tuc27dN6JwCVm7K2huK3dstKjwxmFLW2W/cd+O79kOJFbMZL7AgMBAAECgYArIs/x1mVbHQZ+mLDuss2iW7tJFDFsfA7q0j3uisgtqNO8h0XuP17xx9zNQekKZStZvlYIXjjuem4WaaedKUerUjJa6mktj5+lhRCbqnFjRk6Jw0QJlMAyE3AuRkauKJl121vHD+EzcSiWtT2LE9AsKLlTdAzsZ2RKvaYfaXBsYQJBAPZd5uMtP4FhHLU1wQr08KqSr8H0h1m8V05UFuslR/wZ5ACX/5Eoo7rqGDGuGY3B+4zZE1ZiCoyT1oKLLh+N/okCQQCxJwaC5sgsHTB0IO+nVXQ0DeQC8PWZJ2qBF7wo9faNP4Wne8llH3m7ZMWQiL9dJ/3QOnmaHVI6i5/b1AdxXgRjAkA2TTovxnBh5vK56jAzZwuIvS4qFOikWcPwis5GZAA6y8Yab2YwK4HzF9ffU11khmYYhFwjxRZIJ+m2+lBfOh/pAkEAg0tlLAdXPDq1+puegup2oU3aO8PSgpwP93Vb4w/Il48Iw8Se0u+tDRH2ytRO4AAPwRBVp78rfnCVHhvbGE6R+QJABLGkGvDaAe7LCIwjLweu+Z5jT6qCyLSOp/PcZkdQMXiRW4X8hZlZvl7+zW3lCcTUSq49NlWbN/mVSFGK7Dznwg==
    5 转化为RSAPublicKey的值:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKp8ezVsFmDOCQKcqXFYSDVAtl8H6Yg4ftMnYS57Di3mBfMENNKpeHfoQ8LYDMmo9EfoSHqVxda9GT1JXSMe66r7IPcbHFXeyp2jNihEkg4KCYdahchsioE9t59tuc27dN6JwCVm7K2huK3dstKjwxmFLW2W/cd+O79kOJFbMZL7AgMBAAECgYArIs/x1mVbHQZ+mLDuss2iW7tJFDFsfA7q0j3uisgtqNO8h0XuP17xx9zNQekKZStZvlYIXjjuem4WaaedKUerUjJa6mktj5+lhRCbqnFjRk6Jw0QJlMAyE3AuRkauKJl121vHD+EzcSiWtT2LE9AsKLlTdAzsZ2RKvaYfaXBsYQJBAPZd5uMtP4FhHLU1wQr08KqSr8H0h1m8V05UFuslR/wZ5ACX/5Eoo7rqGDGuGY3B+4zZE1ZiCoyT1oKLLh+N/okCQQCxJwaC5sgsHTB0IO+nVXQ0DeQC8PWZJ2qBF7wo9faNP4Wne8llH3m7ZMWQiL9dJ/3QOnmaHVI6i5/b1AdxXgRjAkA2TTovxnBh5vK56jAzZwuIvS4qFOikWcPwis5GZAA6y8Yab2YwK4HzF9ffU11khmYYhFwjxRZIJ+m2+lBfOh/pAkEAg0tlLAdXPDq1+puegup2oU3aO8PSgpwP93Vb4w/Il48Iw8Se0u+tDRH2ytRO4AAPwRBVp78rfnCVHhvbGE6R+QJABLGkGvDaAe7LCIwjLweu+Z5jT6qCyLSOp/PcZkdQMXiRW4X8hZlZvl7+zW3lCcTUSq49NlWbN/mVSFGK7Dznwg==
    6 公钥加密后的值:Q7i6NzerRdcCSfSTO9yLDza9RE__-D-E_2APn-2QRXe3Yfr2tUsG5oq2PtK2f27-mTX0C6pKA3R3P_8pijhhyOwFO6eV8uJbnW0A0njKihYZUQJe-0-OiNcpLPOr_PtOgBFQh3bM7uBnclDRqeJKMBqQSmjQoDokiipePHmCccA=
    7 要解密长度:172
    8 16
    9 私钥解密后的值:hello world!
    View Code

    抽出方法的代码

      1 package jdk_RSA;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.security.KeyFactory;
      5 import java.security.KeyPair;
      6 import java.security.KeyPairGenerator;
      7 import java.security.NoSuchAlgorithmException;
      8 import java.security.PrivateKey;
      9 import java.security.PublicKey;
     10 import java.security.interfaces.RSAPrivateKey;
     11 import java.security.interfaces.RSAPublicKey;
     12 import java.security.spec.PKCS8EncodedKeySpec;
     13 import java.security.spec.X509EncodedKeySpec;
     14 import java.util.Base64;
     15 
     16 import javax.crypto.Cipher;
     17 
     18 public class RSAjdk {
     19     public static void main(String[] args) {
     20         String content = "hello world!";
     21         System.out.println(content.getBytes().length);
     22         RSAjdk rsa = new RSAjdk();
     23         KeyPair keyPair = rsa.genPairKey();
     24         PrivateKey privateKey = keyPair.getPrivate();
     25         PublicKey publicKey = keyPair.getPublic();
     26         RSAPrivateKey priKey = rsa.getPrivateKey(privateKey);
     27         RSAPublicKey pubKey = rsa.getPublicKey(publicKey);
     28         String encoderContent = rsa.enCoder(pubKey, content);
     29         System.out.println("加密后的字符串:"+encoderContent);
     30         String decoderContent = rsa.deCoder(priKey,encoderContent);
     31         System.out.println("解密后的字符串:"+decoderContent);
     32     }
     33     
     34 //    初始化密钥对儿,不用KeyPair也可以返回void
     35     public KeyPair genPairKey() {
     36         KeyPairGenerator keyPairGenerator = null;
     37         try {
     38             keyPairGenerator = KeyPairGenerator.getInstance("RSA");
     39         } catch (NoSuchAlgorithmException e) {
     40             // TODO Auto-generated catch block
     41             e.printStackTrace();
     42         }
     43 //        初始化生成的密钥对最大长度
     44         keyPairGenerator.initialize(1024);
     45         KeyPair keyPair = keyPairGenerator.generateKeyPair();
     46         return keyPair;
     47     }
     48     
     49 //    取得私钥并经过Base64转化为RSAPrivateKey
     50     public RSAPrivateKey getPrivateKey(PrivateKey privateKey) {
     51         KeyFactory factory = null;
     52         RSAPrivateKey priKey = null;
     53         try {
     54             factory = KeyFactory.getInstance("RSA");
     55             PKCS8EncodedKeySpec pkcs8PrivateKey = new PKCS8EncodedKeySpec(privateKey.getEncoded());
     56             priKey = (RSAPrivateKey) factory.generatePrivate(pkcs8PrivateKey);
     57         } catch (Exception e) {
     58             // TODO Auto-generated catch block
     59             e.printStackTrace();
     60         }
     61         return priKey;
     62     }
     63     
     64 //    取得公钥并经过Base64转化为RSAPublicKey
     65     public RSAPublicKey getPublicKey(PublicKey publicKey) {
     66         KeyFactory factory = null;
     67         RSAPublicKey pubKey = null;
     68         try {
     69             factory = KeyFactory.getInstance("RSA");
     70             X509EncodedKeySpec x509PublicKey = new X509EncodedKeySpec(publicKey.getEncoded());
     71             pubKey = (RSAPublicKey) factory.generatePublic(x509PublicKey);
     72         } catch (Exception e) {
     73             // TODO Auto-generated catch block
     74             e.printStackTrace();
     75         }
     76         return pubKey;
     77     }
     78     
     79 //    公钥加密
     80     public String enCoder(RSAPublicKey key,String content) {
     81         Cipher cipher = null;
     82         byte[] encoderData = null;
     83         String result = null;
     84         try {
     85             cipher = Cipher.getInstance("RSA");
     86             cipher.init(Cipher.ENCRYPT_MODE, key);
     87             encoderData = cipher.doFinal(content.getBytes());
     88             result = Base64.getUrlEncoder().encodeToString(encoderData);
     89         } catch (Exception e) {
     90             // TODO Auto-generated catch block
     91             e.printStackTrace();
     92         } 
     93         return result;
     94     }
     95 //    私钥解密
     96     public String deCoder(RSAPrivateKey key,String content) {
     97         String result = null;
     98         Cipher cipher;
     99         byte[] decoderData = Base64.getUrlDecoder().decode(content.getBytes());
    100         byte[] decoderedData = null;
    101         ByteArrayOutputStream out = new ByteArrayOutputStream();
    102         try {
    103             cipher = Cipher.getInstance("RSA");
    104             cipher.init(Cipher.DECRYPT_MODE, key);
    105             int end = decoderData.length;
    106             byte[] cache = null;
    107             int offset = 0;
    108             int index = 0;
    109             while(end - offset > 0) {
    110                 if(end - offset > 128) {
    111                     cache = cipher.doFinal(decoderData, offset, 128);
    112                 }else {
    113                     cache = cipher.doFinal(decoderData, offset, end-offset);
    114                 }
    115                 out.write(cache, 0, cache.length);
    116                 index++;
    117                 offset = index*128;
    118             }
    119             decoderedData = out.toByteArray();
    120         } catch (Exception e) {
    121             // TODO Auto-generated catch block
    122             e.printStackTrace();
    123         } 
    124         if(decoderedData!=null && decoderData.length!=0) {
    125             result = new String(decoderedData);
    126         }
    127         return result;
    128     }
    129 }

    运行结果:

    1 12
    2 加密后的字符串:m6RE8lEQYBw12u69lyYjxFkr6Lr4EuMv2fmezt7PY-Ty5nY8ld7bMnENodanPnr_b1iaAqm6YfCBUz3lF8ulOPKol8wUts9i1gV-vjMtJmDquWxiaTc7xzS4Z0uWZvAyLKAzTX2rxPjJi3WqqtjkkEkqOfYgwDMDRD-VCVEgN8c=
    3 解密后的字符串:hello world!
    View Code
  • 相关阅读:
    NOIP 转圈游戏
    NOIP 2012 同余方程
    BZOJ3864 Hero meet devil
    HDU3045 Picnic Cows
    「PKUWC2018」随机算法
    CF543E Listening to Music
    CF833E Caramel Clouds
    「PKUWC2018」Slay the Spire
    Luogu2183【国家集训队】礼物
    CF932E Team Work
  • 原文地址:https://www.cnblogs.com/xiaoyao-001/p/9706671.html
Copyright © 2020-2023  润新知