java openssl rsa_Java中使用OpenSSL生成的RSA公私钥进行数据加解密

RSA取名来自Ron Rivest、Adi Shamirh和LenAdleman三个发明者的名字。

RSA原理:RSA算法基于一个十分简单的数论事实,将两个大素数相乘十分容易,但反过来想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

RSA缺点:RSA的keysize位数越高,其产生密钥对及加密、解密的速度越慢,这是基于大素数非对称加密算法的缺陷。

使用OpenSSL来生成私钥和公钥

查看版本信息:

ershixiongdeMacBook-Pro:~ zzs$ openssl version -a

OpenSSL 0.9.8zh 14 Jan 2016

built on: Nov 19 2017

platform: darwin64-x86_64-llvm

options: bn(64,64) md2(int) rc4(ptr,char) des(idx,cisc,16,int) blowfish(idx)

compiler: -arch x86_64 -fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O3 -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DMD32_REG_T=int -DOPENSSL_NO_IDEA -DOPENSSL_PIC -DOPENSSL_THREADS -DZLIB -mmacosx-version-min=10.6

OPENSSLDIR: "/System/Library/OpenSSL"

生成私钥:

ershixiongdeMacBook-Pro:~ zzs$ openssl genrsa -out rsa_private_key.pem 1024

Generating RSA private key, 1024 bit long modulus

..++++++

................++++++

e is 65537 (0x10001)

这条命令让openssl随机生成了一份私钥,加密长度是1024位。加密长度是指理论上最大允许“被加密的信息”长度的限制,也就是明文的长度限制。随着这个参数的增大(比方说2048),允许的明文长度也会增加,但同时也会造成计算复杂度的极速增长。一般推荐的长度就是1024位(128字节)。

ershixiongdeMacBook-Pro:~ zzs$ cat rsa_private_key.pem

-----BEGIN RSA PRIVATE KEY-----

MIICXwIBAAKBgQDQtmuOBLnIcRxy+R7cLMrttBGcNlfTouw4t/dZId5xYd/F76E3

wk3dk0QIYEUVY1bZY8sq7Xv8AzzcnsRi5DM3jxHRl8vGu50TjKLhEG5y+z//LrOe

XyLaKRMPBp1bP9vk4gJrXJGrQpX4aNZEsTor/07tG+onRQXup/RLHS0lkQIDAQAB

AoGBAILcTbV+6wltOjwwTJQaFaZSh9QdEpYkid3KIvEk1jba+hY9+CRg1Ld/tWFX

Exmk7nhhJKqmul05nnhpp5KlqCIjxY5jt1CbX2CxEGN0fJKyzVxKV8Tik9iI246x

vVh6VhbBDhommpjS0TxZNgNowMzXqIhii4sgwmvn0TZ9CCCrCQ2687ey2CyUCGGF

mEpUtrAnMwJBANQFdjrXwxbRmlLU+T3I1P/U2r4B/eW6OdKSGpTQEsbH3uL0rmxn

6funBtaxCzaawkGfUw4FOXEiwBkhcdZWJKj/hvqLTXocw2PLiEKOxqjWjebjAkEA

kqVIdkCf9ht5gws9bQeIk36U4VEdXJSmw8c8TWtxYT4DIrUcI2y2eKDEJ9RYNrop

Wrdh9+yvt7Rr7RswTUQ8ywJBANJ+RdtARPS+nHhddw47lLo000UT38AkCcoa4q9k

F0+mizZUwhJzdOk4qCOM0jSVF0uV/ois4FkE+cfXTdaonyg=

-----END RSA PRIVATE KEY-----

内容都是标准的ASCII字符,开头一行和结尾一行有明显的标记,真正的私钥数据是中间的不规则字符。

密钥文件最终将数据通过Base64编码进行存储。可以看到上述密钥文件内容每一行的长度都很规律。这是由于RFC2045中规定:The encoded output stream must be represented in lines of no more than 76 characters each。也就是说Base64编码的数据每行最多不超过76字符,对于超长数据需要按行分割。

根据私钥生成公钥:

ershixiongdeMacBook-Pro:~ zzs$ openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

writing RSA key

查看公钥内容:

ershixiongdeMacBook-Pro:~ zzs$ cat rsa_public_key.pem

-----BEGIN PUBLIC KEY-----

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQtmuOBLnIcRtBGc

NlfTouw4t/dZId5xYd/F76E3wk3dk0QIYEUVY1bZY8sq7Xv8AzzcjxHR

l8vGu50TjKLhEG5y+rOeXyLaKRMPBp1bP9vk4gJrXJGrQpX4aNZEsTor/07t

G+onRQXup/RLHS0lkQIDAQAB

-----END PUBLIC KEY-----

这时候的私钥还不能直接被使用,需要进行PKCS#8编码:

ershixiongdeMacBook-Pro:~ zzs$ 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)

再来看一下,编码后的私钥文件是不是和之前的私钥文件不同了:

ershixiongdeMacBook-Pro:~ zzs$ cat pkcs8_rsa_private_key.pem

-----BEGIN PRIVATE KEY-----

MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBANC2a44EuchxHHL5

Htwsyu20EZw2V9Oi7Di391kh3nFh38XvoTfCTd2TRAhgRRVjVtljyyrte/wDPNye

xGLkMzePEdGXy8a7nROMouEQbnL7P/8us55fItopEw8GnVs/2+TiAmtckatClfho

1B0SliSJ3coi8STWNtr6Fj34JGDUt3+1YVcTGaTueGEkqqa6XTmeeGmnkqWoIiPF

G4Wl9VIhfxnh/DA0BJ0CQQD8AUKXMzKYdAC9WHpWFsEOGiaamNLRPFk2A2jAzNeo

iGKLiyDCa+fRNn0IIKsJDbrzt7LYLJQIYYWYSlS2sCczAkEA1AV2OtfDFtGaUtT5

fM8wKwJBAMKC0nxURzRHLZ74oQy76W1SIAPp+6cG1rELNprCQZ9TDgU5cSLAGSFx

1lYkqP+G+otNehzDY8uIQo7GqNaN5uMCQQCSpUh2QJ/2G3mDCz1tB4iTfpThUR1c

20BE9L6ceF13DjuUujTTRRPfwCQJyhrir2QXT6aLNlTCEnN06TioI4zSNJUXS5X+

iKzgWQT5x9dN1qifKA==

-----END PRIVATE KEY-----

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

第一步生成的私钥文件编码是PKCS#1格式,这种格式Java其实是支持的,只不过多写两行代码而已:

RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(priKeyData));

RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());

KeyFactory keyFactory= KeyFactory.getInstance("RSA");

PrivateKey priKey= keyFactory.generatePrivate(rsaPrivKeySpec);

首先将PKCS#1的私钥文件读取出来(注意去掉减号开头的注释内容),然后使用Base64解码读出的字符串,便得到priKeyData,也就是第一行代码中的参数。最后一行得到了私钥。接下来的用法就没什么区别了。

参考文献:https://community.oracle.com/thread/1529240?start=0&tstart=0

加载公钥与加载私钥的不同点在于公钥加载时使用的是X509EncodedKeySpec(X509编码的Key指令),私钥加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值