美文网首页
openssl生成RSA格式及pkcs1与pkcs8格式互相转换

openssl生成RSA格式及pkcs1与pkcs8格式互相转换

作者: 一杯茶一本书 | 来源:发表于2020-02-19 15:14 被阅读0次

    openssl简介

    OpenSSL 是一个开源项目,其组成主要包括一下三个组件:

    • openssl:多用途的命令行工具
    • libcrypto:加密算法库
    • libssl:加密模块应用库,实现了ssl及tls

    openssl可以实现:密钥证书管理、对称加密和非对称加密等,想了解更多搜索查看官网。接下来主要围绕openssl生成RSA格式及pkcs1与pkcs8格式互相转换。

    配置RSA密钥

    可以参考支付宝配置密钥:https://docs.open.alipay.com/common/104740
    如图:

    支付宝配置密钥
    
    生成命令使用说明:
     
      RSA密钥生成命令
      生成RSA私钥
      openssl>genrsa -out rsa_private_key.pem 1024
      生成RSA公钥
      openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
      将RSA私钥转换成PKCS8格式
      openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out pkcs8.pem
     
      注意:“>”符号后面的才是需要输入的命令。
    
    

    具体操作:
    openssl默认使用的是PEM格式,经过base64。

    生成pem格式的私钥:

    openssl genrsa -out private_key.pem 1024

    [root@VM_0_2_centos sign]# openssl genrsa -out private_key.pem 1024
    Generating RSA private key, 1024 bit long modulus
    ............................++++++
    ..................................................++++++
    e is 65537 (0x10001)
    [root@VM_0_2_centos sign]# ls
    private_key.pem
    [root@VM_0_2_centos sign]# cat private_key.pem
    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQDH2m9FfHSMZlT1t0PfQDCNHIzvnbhq6+WlxEWTHETVKe3wHR/E
    7TgqIYVRU0M1X2Jb7AKtopqer2PqS+AnTC1dUWDtxcYWdvIaYAgTEyhlvaEpX8kc
    g2TW+X1VfJuw02nbimfGPcRQFVrJW2UJkAuF3jVyhy0wnfovclcEEPmaWwIDAQAB
    AoGBAIY/NdWQV13kc5em5oG1xadUkVt4L+Qq19V1NWMvbxFdnAZaGfgXfU3XvI03
    iAL3MsQakmX+vyxvFofRNh5Prnw7sQVu0EIH4LLDb4M7xjxQJMhwsHC6hqzYjDr2
    a5UCwEggg1UTidt3a7cZgO3RGocsM0b1RF1b77fDDjgpyGdZAkEA7RcSX0ZrvX+J
    u6iGylQcaJV56r4vlXqzusjn4drgLOizFLF/QkQp/MqN9zqCOvZioPv4pzNaYsBS
    Wj/gOnLvHQJBANfLDqB+sljmeXlJiKX6sejWQKElOZcvasgR0/b0dPGVBfWzXEc5
    ypfTpNd/Z5NfU1xtCziht2LWnNCZYWWmndcCQQCSwPM4UiiidW1V4Sz91C55dfyv
    FuXxSrAxb+ZIYOjeI3Ol3XB+Hh83QFG7tFWkFZpbN1xkcl8CPTU8c8lhpH7pAkEA
    zK1T7VTessXAOBNQIiZbsv3tBSu6qTSXcra+NsF9Xlq78WUzRHeDOmjLNH8qbbT/
    622eNBPnTj9DM/QXVoQntwJAAjNM2+FpeC+hJvyBFCk2bSt17pmJGTfiFDgn6/zK
    cTvmQC1kIb524j1hLp15ZLneBB4lhpB0mFWJsaaXioWloA==
    -----END RSA PRIVATE KEY-----
    

    生成公钥:

    openssl rsa -in private_key.pem -pubout -out public_key.pem

    [root@VM_0_2_centos sign]# openssl rsa -in private_key.pem -pubout -out public_key.pem
    writing RSA key
    [root@VM_0_2_centos sign]# ls
    private_key.pem  public_key.pem
    [root@VM_0_2_centos sign]# cat public_key.pem
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH2m9FfHSMZlT1t0PfQDCNHIzv
    nbhq6+WlxEWTHETVKe3wHR/E7TgqIYVRU0M1X2Jb7AKtopqer2PqS+AnTC1dUWDt
    xcYWdvIaYAgTEyhlvaEpX8kcg2TW+X1VfJuw02nbimfGPcRQFVrJW2UJkAuF3jVy
    hy0wnfovclcEEPmaWwIDAQAB
    -----END PUBLIC KEY-----
    

    pkcs8格式私钥

    某些语言需要pkcs8格式的私钥。 (php就不需要了)
    使用openssl将刚才生成的私钥转为pkcs#8格式:
    openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out private_key_pkcs8.pem

    [root@VM_0_2_centos sign]# openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out private_key_pkcs8.pem
    [root@VM_0_2_centos sign]#
    [root@VM_0_2_centos sign]#  ls
    private_key.pem  private_key_pkcs8.pem  public_key.pem
    [root@VM_0_2_centos sign]# cat private_key_pkcs8.pem
    -----BEGIN PRIVATE KEY-----
    MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMfab0V8dIxmVPW3
    Q99AMI0cjO+duGrr5aXERZMcRNUp7fAdH8TtOCohhVFTQzVfYlvsAq2imp6vY+pL
    4CdMLV1RYO3FxhZ28hpgCBMTKGW9oSlfyRyDZNb5fVV8m7DTaduKZ8Y9xFAVWslb
    ZQmQC4XeNXKHLTCd+i9yVwQQ+ZpbAgMBAAECgYEAhj811ZBXXeRzl6bmgbXFp1SR
    W3gv5CrX1XU1Yy9vEV2cBloZ+Bd9Tde8jTeIAvcyxBqSZf6/LG8Wh9E2Hk+ufDux
    BW7QQgfgssNvgzvGPFAkyHCwcLqGrNiMOvZrlQLASCCDVROJ23drtxmA7dEahywz
    RvVEXVvvt8MOOCnIZ1kCQQDtFxJfRmu9f4m7qIbKVBxolXnqvi+VerO6yOfh2uAs
    6LMUsX9CRCn8yo33OoI69mKg+/inM1piwFJaP+A6cu8dAkEA18sOoH6yWOZ5eUmI
    pfqx6NZAoSU5ly9qyBHT9vR08ZUF9bNcRznKl9Ok139nk19TXG0LOKG3Ytac0Jlh
    Zaad1wJBAJLA8zhSKKJ1bVXhLP3ULnl1/K8W5fFKsDFv5khg6N4jc6XdcH4eHzdA
    Ubu0VaQVmls3XGRyXwI9NTxzyWGkfukCQQDMrVPtVN6yxcA4E1AiJluy/e0FK7qp
    NJdytr42wX1eWrvxZTNEd4M6aMs0fypttP/rbZ40E+dOP0Mz9BdWhCe3AkACM0zb
    4Wl4L6Em/IEUKTZtK3XumYkZN+IUOCfr/MpxO+ZALWQhvnbiPWEunXlkud4EHiWG
    kHSYVYmxppeKhaWg
    -----END PRIVATE KEY-----
    

    pkcs1与pkcs8格式互相转换

    传统私钥格式转PKCS8在文中上面已经给出 ,这里主要是PKCS8格式私钥转换为PKCS1(传统私钥格式)
    命令:openssl rsa -in pkcs8.pem -out pri_key.pem

    [root@VM_0_2_centos sign]# openssl rsa -in private_key_pkcs8.pem -out pri_key.pem
    writing RSA key
    [root@VM_0_2_centos sign]# cat pri_key.pem
    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQDH2m9FfHSMZlT1t0PfQDCNHIzvnbhq6+WlxEWTHETVKe3wHR/E
    7TgqIYVRU0M1X2Jb7AKtopqer2PqS+AnTC1dUWDtxcYWdvIaYAgTEyhlvaEpX8kc
    g2TW+X1VfJuw02nbimfGPcRQFVrJW2UJkAuF3jVyhy0wnfovclcEEPmaWwIDAQAB
    AoGBAIY/NdWQV13kc5em5oG1xadUkVt4L+Qq19V1NWMvbxFdnAZaGfgXfU3XvI03
    iAL3MsQakmX+vyxvFofRNh5Prnw7sQVu0EIH4LLDb4M7xjxQJMhwsHC6hqzYjDr2
    a5UCwEggg1UTidt3a7cZgO3RGocsM0b1RF1b77fDDjgpyGdZAkEA7RcSX0ZrvX+J
    u6iGylQcaJV56r4vlXqzusjn4drgLOizFLF/QkQp/MqN9zqCOvZioPv4pzNaYsBS
    Wj/gOnLvHQJBANfLDqB+sljmeXlJiKX6sejWQKElOZcvasgR0/b0dPGVBfWzXEc5
    ypfTpNd/Z5NfU1xtCziht2LWnNCZYWWmndcCQQCSwPM4UiiidW1V4Sz91C55dfyv
    FuXxSrAxb+ZIYOjeI3Ol3XB+Hh83QFG7tFWkFZpbN1xkcl8CPTU8c8lhpH7pAkEA
    zK1T7VTessXAOBNQIiZbsv3tBSu6qTSXcra+NsF9Xlq78WUzRHeDOmjLNH8qbbT/
    622eNBPnTj9DM/QXVoQntwJAAjNM2+FpeC+hJvyBFCk2bSt17pmJGTfiFDgn6/zK
    cTvmQC1kIb524j1hLp15ZLneBB4lhpB0mFWJsaaXioWloA==
    -----END RSA PRIVATE KEY-----
    [root@VM_0_2_centos sign]#
    

    根据结果可知和上面生成的私钥是一致的

    加解密demo代码

    PHP版

    <?php 
    $pri = "-----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQDH2m9FfHSMZlT1t0PfQDCNHIzvnbhq6+WlxEWTHETVKe3wHR/E
    7TgqIYVRU0M1X2Jb7AKtopqer2PqS+AnTC1dUWDtxcYWdvIaYAgTEyhlvaEpX8kc
    g2TW+X1VfJuw02nbimfGPcRQFVrJW2UJkAuF3jVyhy0wnfovclcEEPmaWwIDAQAB
    AoGBAIY/NdWQV13kc5em5oG1xadUkVt4L+Qq19V1NWMvbxFdnAZaGfgXfU3XvI03
    iAL3MsQakmX+vyxvFofRNh5Prnw7sQVu0EIH4LLDb4M7xjxQJMhwsHC6hqzYjDr2
    a5UCwEggg1UTidt3a7cZgO3RGocsM0b1RF1b77fDDjgpyGdZAkEA7RcSX0ZrvX+J
    u6iGylQcaJV56r4vlXqzusjn4drgLOizFLF/QkQp/MqN9zqCOvZioPv4pzNaYsBS
    Wj/gOnLvHQJBANfLDqB+sljmeXlJiKX6sejWQKElOZcvasgR0/b0dPGVBfWzXEc5
    ypfTpNd/Z5NfU1xtCziht2LWnNCZYWWmndcCQQCSwPM4UiiidW1V4Sz91C55dfyv
    FuXxSrAxb+ZIYOjeI3Ol3XB+Hh83QFG7tFWkFZpbN1xkcl8CPTU8c8lhpH7pAkEA
    zK1T7VTessXAOBNQIiZbsv3tBSu6qTSXcra+NsF9Xlq78WUzRHeDOmjLNH8qbbT/
    622eNBPnTj9DM/QXVoQntwJAAjNM2+FpeC+hJvyBFCk2bSt17pmJGTfiFDgn6/zK
    cTvmQC1kIb524j1hLp15ZLneBB4lhpB0mFWJsaaXioWloA==
    -----END RSA PRIVATE KEY-----";
     
    $pub = "-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH2m9FfHSMZlT1t0PfQDCNHIzv
    nbhq6+WlxEWTHETVKe3wHR/E7TgqIYVRU0M1X2Jb7AKtopqer2PqS+AnTC1dUWDt
    xcYWdvIaYAgTEyhlvaEpX8kcg2TW+X1VfJuw02nbimfGPcRQFVrJW2UJkAuF3jVy
    hy0wnfovclcEEPmaWwIDAQAB
    -----END PUBLIC KEY-----";
     
     
    $data = "message";
     
    echo "\n<br/>\n";
    openssl_public_encrypt($data, $crypted, $pub);
    echo base64_encode($crypted);
     
    echo "\n<br/>\n";
     
    openssl_private_decrypt($crypted, $decrypted, $pri);
    echo $decrypted;
    ?>
    

    Java版

    import java.security.KeyFactory;
    import java.security.PublicKey;
     
    import sun.misc.*;
     
    import java.security.PrivateKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
     
    import javax.crypto.Cipher;
     
    import sun.misc.BASE64Decoder;
     
    public class TestRSA {
     
        public static String PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----" + "\n" +
                "MIICXAIBAAKBgQCd3V5+GjpOwqNks9ProDGaZT2qURAAuAodHcUM3P1mnhOh4l4u" + "\n" +
                "VdvkXunUI7K6XDg6Xu9eL1WDQc6qKXs/OD91LS+RpkIAb2gMU8hGrNfR34izZh36" + "\n" +
                "KdfWnEQpniAiFsHsg2ddAaPtGZZ8/jpjuPq32IVZJkgyKcWqnz5aL3FMXQIDAQAB" + "\n" +
                "AoGAJFdkvGTvTVhTYwhe3dxn7uIlmwLES1YSxfcneLmbADedz2OcSNBtKZqL+9Eo" + "\n" +
                "AOzf6NgYBLei2O+aUuPvwnMBcGyijFmRoZGVEj70UP0mngyAkvY/juA60QDe5kY5" + "\n" +
                "rsqj4raHUf4iDK85nNwzXu7hIlPAn+ZmH+e2Eekwo1rmgQUCQQDJerucfBKk3qrV" + "\n" +
                "xS5NRW99lKMomIsMH55Si+rbrnk8aU3SSRSD6uil3Dytv0erLZbc9d0Nr6SmBZgO" + "\n" +
                "0qzOjXDDAkEAyJVGgHMNuMbpHnim93HAP7wcejmMx7rP4zutw4OCiHrWv3kN8WUC" + "\n" +
                "u826taRFtOuiXhQ3X8+tb0l4ifae+vJ8XwJAEcmuKqChnMCz4G+qKNRKhZHL3dep" + "\n" +
                "3wYjmjIUKBT9SyIY5sng78ybgZkyGjza/Pfna9ahD4ZESQwRYq2i6BGAtQJBAJyD" + "\n" +
                "bmnYXQKro0e1mYNHbV3OKOJueZ139bM35BTFT1uzjlIF4Y1U5lco5uHJduL/YsjK" + "\n" +
                "OZM3d/t4duggWlkyUT0CQBdsjc7eQ9roxphrW4Q/6Zwi0EQ4xxM4SgxPY1RvkKFu" + "\n" +
                "i0HdYBj5KRdIbrAbisUyQeKzB7+6oTJH5+kZAU/pxao=" + "\n" +
                "-----END RSA PRIVATE KEY-----";
         
        public static String PRIVATE_KEY_PKCS8 = "-----BEGIN PRIVATE KEY-----" + "\n" +
                "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ3dXn4aOk7Co2Sz" + "\n" +
                "0+ugMZplPapREAC4Ch0dxQzc/WaeE6HiXi5V2+Re6dQjsrpcODpe714vVYNBzqop" + "\n" +
                "ez84P3UtL5GmQgBvaAxTyEas19HfiLNmHfop19acRCmeICIWweyDZ10Bo+0Zlnz+" + "\n" +
                "OmO4+rfYhVkmSDIpxaqfPlovcUxdAgMBAAECgYAkV2S8ZO9NWFNjCF7d3Gfu4iWb" + "\n" +
                "AsRLVhLF9yd4uZsAN53PY5xI0G0pmov70SgA7N/o2BgEt6LY75pS4+/CcwFwbKKM" + "\n" +
                "WZGhkZUSPvRQ/SaeDICS9j+O4DrRAN7mRjmuyqPitodR/iIMrzmc3DNe7uEiU8Cf" + "\n" +
                "5mYf57YR6TCjWuaBBQJBAMl6u5x8EqTeqtXFLk1Fb32UoyiYiwwfnlKL6tuueTxp" + "\n" +
                "TdJJFIPq6KXcPK2/R6stltz13Q2vpKYFmA7SrM6NcMMCQQDIlUaAcw24xukeeKb3" + "\n" +
                "ccA/vBx6OYzHus/jO63Dg4KIeta/eQ3xZQK7zbq1pEW066JeFDdfz61vSXiJ9p76" + "\n" +
                "8nxfAkARya4qoKGcwLPgb6oo1EqFkcvd16nfBiOaMhQoFP1LIhjmyeDvzJuBmTIa" + "\n" +
                "PNr89+dr1qEPhkRJDBFiraLoEYC1AkEAnINuadhdAqujR7WZg0dtXc4o4m55nXf1" + "\n" +
                "szfkFMVPW7OOUgXhjVTmVyjm4cl24v9iyMo5kzd3+3h26CBaWTJRPQJAF2yNzt5D" + "\n" +
                "2ujGmGtbhD/pnCLQRDjHEzhKDE9jVG+QoW6LQd1gGPkpF0husBuKxTJB4rMHv7qh" + "\n" +
                "Mkfn6RkBT+nFqg==" + "\n" +
                "-----END PRIVATE KEY-----";
     
        public static String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----" + "\n" +
                "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCd3V5+GjpOwqNks9ProDGaZT2q" + "\n" +
                "URAAuAodHcUM3P1mnhOh4l4uVdvkXunUI7K6XDg6Xu9eL1WDQc6qKXs/OD91LS+R" + "\n" +
                "pkIAb2gMU8hGrNfR34izZh36KdfWnEQpniAiFsHsg2ddAaPtGZZ8/jpjuPq32IVZ" + "\n" +
                "JkgyKcWqnz5aL3FMXQIDAQAB" + "\n" +
                "-----END PUBLIC KEY-----";
         
        public static void main(String[] args) {
             
            String text = "message";
             
            try {
                String priStr = PRIVATE_KEY_PKCS8.replaceAll("-----BEGIN PRIVATE KEY-----\n", "");
                priStr = priStr.replaceAll("-----END PRIVATE KEY-----", "");
                byte [] privateKeyBytes = new BASE64Decoder().decodeBuffer(priStr);
                PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
                 
                Cipher cipher = Cipher.getInstance("RSA"); 
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                 
                byte[] crypted = cipher.doFinal(text.getBytes());
                 
                System.out.println(new BASE64Encoder().encode(crypted));
                 
                 
                //  decrypt blow.
                 
                String pubStr = PUBLIC_KEY.replaceAll("-----BEGIN PUBLIC KEY-----\n", "");
                pubStr = pubStr.replaceAll("-----END PUBLIC KEY-----", "");
                byte [] publicKeyBytes = new BASE64Decoder().decodeBuffer(pubStr);
                X509EncodedKeySpec  pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
                keyFactory = KeyFactory.getInstance("RSA");
                PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
                 
                cipher = Cipher.getInstance("RSA"); 
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                 
                byte[] bytes = cipher.doFinal(crypted);
                System.out.println(new String(bytes, "ISO-8859-1"));
                 
                 
            } catch (Exception e) {
                e.printStackTrace();
            }
             
        }
     
    }
    
    

    需要注意的是,java的代码中的private key必须使用pkcs#8格式的。
    java加密 php解密 也是没问题的!
    感谢大家的阅读,也希望能转发并关注我的公众号(帝都小崔Cayden)或搜索code_cayden

    相关文章

      网友评论

          本文标题:openssl生成RSA格式及pkcs1与pkcs8格式互相转换

          本文链接:https://www.haomeiwen.com/subject/gdyafhtx.html