zoukankan      html  css  js  c++  java
  • RSA加密解密中pkcs1与pkcs8格式私钥互相转换

    net,ios中rsa加解密使用的是pkcs1,而java使用的是pkcs8

    如果是按1024取模(通常都是1024),pkcs1格式的私钥长度应该是812。如果是pkcs8的格式的密钥长度为861。

    下载安装openssl:https://pan.baidu.com/s/1ggQJIIR

    我这边使用的是Win64OpenSSL_Light-1_1_0g.exe

    PKCS1私钥生成:

    OpenSSL> genrsa -out pkcs1_private.pem 1024
    Generating RSA private key, 1024 bit long modulus
    .........++++++
    .............................++++++
    e is 65537 (0x10001)

    内容:

    -----BEGIN RSA PRIVATE KEY-----
    MIICWwIBAAKBgQCYMTaH4NMw5fQsgx3pv8xaAxhOdtUz/m5nfl9XHtGboXNzUzx/
    ehh8c3RgpGcig83JXOYOXafmx3OS28Ed3e2fmC5Yo5RD6DRHnBCid28EjQ5PgCTd
    dNqDvcXU3YMH4sO1qNBx5MQpk92Kt/NdquIJmzhgpjP15MO5CFHcU90ZvQIDAQAB
    AoGANlvdjkrPI/f+bqemV4caBkx0shHftOJ7rJuGkid/1oakJdzlDuMdO9ZBCwOt
    krZhGjsEML1i6xryPNIg9/n8lSdQqIUW61HXYwKUK5xQWz/MstWbbIx3t5driQFR
    Fv53NLdemeF/0AJiD5COO1fkoM+1By2LlI0ths8cQLcOpgECQQDIc46yV1N5IuS0
    MYD0LgggaJ08WF0PrwjXgs+DRp3+ZE5WTs1JDkBQM9E598xbmy7AAFtdtR3L5CH8
    5Qh+KfwJAkEAwl4MuRMdIjiHiw1YoIUliy6t3XPvxeOEiG/P15adKrxI5A5QylM0
    TtbZT3YZurdy3nrJ75LxuU9cSYKzxtVFFQJAMboJElD7kjeHyPPm66xns7KAHzJE
    k9l2NhBrbkOcejlj/aE65/6zEbJpGxpQBgGvTU5JXCvMIoKLs/MVckb0EQJASze+
    ULkW4zFhMuy9SZF9T/mGi1bciYZcubgbhODifbFTu/3WQhYk/gWjH18i4eEwcOyv
    zSjepsoRetk73UyXaQJAOfr3Gg1dGvoLiwZ3fXoDVupahnKg73SAd72+24qQs2AT
    16T8FKop259xisLu+WSUTfSUhao5qOpZJ/PTwFRlzw==
    -----END RSA PRIVATE KEY-----

    PKCS1私钥转换为PKCS8(该格式一般Java调用)

    OpenSSL>  pkcs8 -topk8 -inform PEM -in pkcs1_private.pem -outform pem -nocrypt -out pkcs8_private.pem

    内容:

    -----BEGIN PRIVATE KEY-----
    MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJgxNofg0zDl9CyD
    Hem/zFoDGE521TP+bmd+X1ce0Zuhc3NTPH96GHxzdGCkZyKDzclc5g5dp+bHc5Lb
    wR3d7Z+YLlijlEPoNEecEKJ3bwSNDk+AJN102oO9xdTdgwfiw7Wo0HHkxCmT3Yq3
    812q4gmbOGCmM/Xkw7kIUdxT3Rm9AgMBAAECgYA2W92OSs8j9/5up6ZXhxoGTHSy
    Ed+04nusm4aSJ3/WhqQl3OUO4x071kELA62StmEaOwQwvWLrGvI80iD3+fyVJ1Co
    hRbrUddjApQrnFBbP8yy1ZtsjHe3l2uJAVEW/nc0t16Z4X/QAmIPkI47V+Sgz7UH
    LYuUjS2GzxxAtw6mAQJBAMhzjrJXU3ki5LQxgPQuCCBonTxYXQ+vCNeCz4NGnf5k
    TlZOzUkOQFAz0Tn3zFubLsAAW121HcvkIfzlCH4p/AkCQQDCXgy5Ex0iOIeLDVig
    hSWLLq3dc+/F44SIb8/Xlp0qvEjkDlDKUzRO1tlPdhm6t3LeesnvkvG5T1xJgrPG
    1UUVAkAxugkSUPuSN4fI8+brrGezsoAfMkST2XY2EGtuQ5x6OWP9oTrn/rMRsmkb
    GlAGAa9NTklcK8wigouz8xVyRvQRAkBLN75QuRbjMWEy7L1JkX1P+YaLVtyJhly5
    uBuE4OJ9sVO7/dZCFiT+BaMfXyLh4TBw7K/NKN6myhF62TvdTJdpAkA5+vcaDV0a
    +guLBnd9egNW6lqGcqDvdIB3vb7bipCzYBPXpPwUqinbn3GKwu75ZJRN9JSFqjmo
    6lkn89PAVGXP
    -----END PRIVATE KEY-----

    生成公钥:

    PKCS1的私钥生成公钥:

    OpenSSL> rsa -in pkcs1_private.pem -pubout -out pkcs1_public.pem
    writing RSA key

    内容:

    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYMTaH4NMw5fQsgx3pv8xaAxhO
    dtUz/m5nfl9XHtGboXNzUzx/ehh8c3RgpGcig83JXOYOXafmx3OS28Ed3e2fmC5Y
    o5RD6DRHnBCid28EjQ5PgCTddNqDvcXU3YMH4sO1qNBx5MQpk92Kt/NdquIJmzhg
    pjP15MO5CFHcU90ZvQIDAQAB
    -----END PUBLIC KEY-----

    PKCS8的私钥生成公钥:

    OpenSSL> rsa -in pkcs8_private.pem -pubout -out pkcs8_public.pem
    writing RSA key

    内容:

    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYMTaH4NMw5fQsgx3pv8xaAxhO
    dtUz/m5nfl9XHtGboXNzUzx/ehh8c3RgpGcig83JXOYOXafmx3OS28Ed3e2fmC5Y
    o5RD6DRHnBCid28EjQ5PgCTddNqDvcXU3YMH4sO1qNBx5MQpk92Kt/NdquIJmzhg
    pjP15MO5CFHcU90ZvQIDAQAB
    -----END PUBLIC KEY-----

    结果发现两个公钥都是一样的。

    下面链接里面有在线生产地址:http://tool.chacuo.net/cryptrsapkcs1pkcs8

    上面的转换都没有私钥密码

    注意:

    使用rsa进行加密的时候,如果报不正常长度,那么就要进行分段加解密。

    RSA加解密:
    
    1024位的证书,加密时最大支持117个字节,解密时为128;
    2048位的证书,加密时最大支持245个字节,解密时为256。
    
    加密时支持的最大字节数:证书位数/8 -11(比如:2048位的证书,支持的最大加密字节数:2048/8 - 11 = 245)
    
    .NET中的RSA加密算法为了提高安全性,在待加密数据前要添加一些随机数,因此,使用.NET中的RSA加密算法一次最多加密117字节数据(多于117字节需要拆分成多段分别加密再连接起来),经过加密后得到一个长度为128字节的加密数据。
    
    RSA实际可加密的明文长度最大也是1024bits,但问题就来了:如果小于这个长度怎么办?就需要进行padding,因为如果没有padding,用户无法区分解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,

    但对二进制数据就很难理解,因为不确定后面的0是内容还是内容结束符。只要用到padding,那么就要占用实际的明文长度,于是才有117字节的说法。
    我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。
    如果大于这个长度怎么办?很多算法的padding往往是在后边的,但PKCS的padding则是在前面的,此为有意设计,有意的把第一个字节置0以确保m的值小于n。
    这样,128字节(1024bits)
    -减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。

    在对接中使用流程:

    一共有两组四个密钥:A的公钥(PUB_A),A的私钥(PRI_A);B的公钥(PUB_B),B的私钥(PRI_B)。
    公钥一般用来加密,私钥用来签名。
    通常公钥是公开出去的,但是私钥只能自己私密持有。
    公钥和私钥唯一对应,用某个公钥签名过得内容只能用对应的私钥才能解签验证;同样用某个私钥加密的内容只能用对应的公钥才能解密。
    这时A向B发送信息的整个签名和加密的过程如下:
    1、A先用自己的私钥(PRI_A)对信息(一般是信息的摘要)进行签名。
    2、A接着使用B的公钥(PUB_B)对信息内容和签名信息进行加密。
    这样当B接收到A的信息后,获取信息内容的步骤如下:
    1、用自己的私钥(PRI_B)解密A用B的公钥(PUB_B)加密的内容;
    2、得到解密后的明文后用A的公钥(PUB_A)解签A用A自己的私钥(PRI_A)的签名。
    从而整个过程就保证了开始说的端到端的唯一确认。A的签名只有A的公钥才能解签,这样B就能确认这个信息是A发来的;A的加密只有B的私钥才能解密,这样A就能确认这份信息只能被B读取。

    但是在我的使用过程中,发现只能公钥加密,私钥解密,反之则不可以,私钥可以用来加签,对应的公钥可以用来验签。(应该是我哪里没搞懂,所以在不能私钥加密,公钥解密)

    现在一般对接就是

    1.用对方的私钥对消息进行加签生成sign,再将消息message跟sign使用对方的公钥进行加密

    2.对方接收到数据以后,先用自己的私钥进行解密,再用私钥对解密出来的message进行加签,与传递过来的sign进行对比

    RSA只是一个加密的算法,加签需要先对内容进行HASH然后再加密,比如SHA1WithRSA就是一个常用的RSA加签算法。

    https://www.jianshu.com/p/08e41304edab

    https://www.cnblogs.com/littleatp/p/5878763.html

  • 相关阅读:
    ExtJS小技巧
    Oracle 表的行数、表占用空间大小,列的非空行数、列占用空间大小 查询
    NPM 私服
    IDEA 不编译java以外的文件
    SQL 引号中的问号在PrepareStatement 中不被看作是占位符
    Chrome 浏览器自动填表呈现淡黄色解决
    批量删除Maven 仓库未下载成功.lastupdate 的文件
    Oracle 11g 监听很慢,由于监听日志文件太大引起的问题(Windows 下)
    Hibernate 自动更新表出错 建表或添加列,提示标识符无效
    Hibernate 自动更新表出错 More than one table found in namespace
  • 原文地址:https://www.cnblogs.com/hongdada/p/8295526.html
Copyright © 2011-2022 走看看