java中rsa非对称密钥加解密使用示例,Java中RSA非对称密钥加解密使用示例

Rs1z4Sj3oA%Z0一、简介:]T+v#k.HYv

wML0

8ec"E5rm&R0`wj#X-m0jI0RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。

RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定

RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。51Testing软件测试网 ZG%~uV6Y%i,fk51Testing软件测试网"m"_Y6CA-\vm2A

二、RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表"x#Bpceo^0

9z`9Q&LSJO0三、使用方式:Q)~9f.SwTj]6Lf051Testing软件测试网xBK+rpqs

① 假设A、B机器进行通信,已A机器为主;ma$bdh+v4X0

o(bW?M0② A首先需要用自己的私钥为发送请求数据签名,并将公钥一同发送给B;vW)sy8gBI051Testing软件测试网`}"`U^EE

③ B收到数据后,需要用A发送的公钥进行验证,已确保收到的数据是未经篡改的;51Testing软件测试网(^cZ+^(k6bEQP

nu6g^lu3^0④ B验签通过后,处理逻辑,并把处理结果返回,返回数据需要用A发送的公钥进行加密(公钥加密后,只能用配对的私钥解密);51Testing软件测试网9HP[7KQi2xT

W

|$v?on%h V7ZG0⑤ A收到B返回的数据,使用私钥解密,至此,一次数据交互完成。j.FxC~7kcbv:E051Testing软件测试网BM7b`O+b

四、代码示例:4g-VO9@*N(F'gX)[051Testing软件测试网 k!}u+M(L-JK*E

1、第一步获取私钥,为签名做准备。%GCab%L"|L(Oi-vti0/**

&}C9E-[$i.xPC0     * 读取私钥  返回PrivateKey51Testing软件测试网'@zF#_TVKtkw0y\

* @param path  包含私钥的证书路径

Trb(V3Aay3H0     * @param password  私钥证书密码

X7T-{B9@i`0     * @return 返回私钥PrivateKey51Testing软件测试网#[#\;q`9M$mTr$l

* @throws KeyStoreException

Jx[E)]mKV0     * @throws NoSuchAlgorithmException51Testing软件测试网]^&x7ch|

* @throws CertificateException

8_ ?}3hAz-`7k0     * @throws IOException

7^0v.E(o-wg0     * @throws UnrecoverableKeyException

!A/hYmd ?p0     */

M S/~Rk0    private static PrivateKey getPrivateKey(String path,String password)

UU

EQ!U;^b1g0            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,

;kR8[@pq8Z5m0            IOException, UnrecoverableKeyException {

s3wf-^}0        KeyStore ks = KeyStore.getInstance("PKCS12");51Testing软件测试网6v:K8r5z1p2?9qt

FileInputStream fis = new FileInputStream(path);

5QvA'KMH0        char[] nPassword = null;

2n*t`9z*W8\0        if ((password == null) || password.trim().equals("")) {51Testing软件测试网RPC+{0lc)\+Uka/I3d(L

nPassword = null;

ee%e5fw/l/x0        } else {

5G9Bp/Y$~0            nPassword = password.toCharArray();

sIu[s2gm0B'K0        }

,_TF3I&]s)nFM0        ks.load(fis, nPassword);51Testing软件测试网i!I"iY:PY,h3r;m

fis.close();

x6G!l|a:@`F7J m0        Enumeration en = ks.aliases();51Testing软件测试网C$p*G6J;Y_R

String keyAlias = null;

BL s2MnHA7J0        if (en.hasMoreElements()) {

6~z+P[ZNJP0            keyAlias = (String) en.nextElement();

KTN~\_HE;n`f!d,E0        }

W8U#UX{Gf|4Z0 51Testing软件测试网nH3C2M oK

return (PrivateKey) ks.getKey(keyAlias, nPassword);

wSXG%V/i*?0    }51Testing软件测试网3e3[q#Q3H6aU3p&H

2、签名示例:通过第一步得到的私钥,进行签名操作,具体请看以下代码:51Testing软件测试网V? C4m!|$b1j6z/**51Testing软件测试网3]S0q,u|6O&[a'GQ

* 私钥签名: 签名方法如下:BASE64(RSA(MD5(src),privatekey)),其中src为需要签名的字符串,51Testing软件测试网2o)PY"V-IO6a_!W3[iI

privatekey是商户的CFCA证书私钥。

4W"sM&Ly'_W0     * @param plainText 待签名字符串51Testing软件测试网G3WtJ(^

* @param path 签名私钥路径51Testing软件测试网0n;nIW:nj6kd

* @param password  签名私钥密码

WgNff

fv&{hk0     * @return 返回签名后的字符串

:J7a;kG5S!s0     * @throws Exception51Testing软件测试网2n.i9bI\s)[ ^

*/

6]8mR_7`?0    public static String sign(String plainText,String path,String password)51Testing软件测试网C?J e8g6R;U0_9A

throws Exception  {51Testing软件测试网xCD/j!y]^

/*51Testing软件测试网|@^&cT;v(Kk3}oz

* MD5加密51Testing软件测试网&if:T&Y@5J

*/

I"nhe L:W~'`s0        MessageDigest md5 = MessageDigest.getInstance("MD5");51Testing软件测试网7Gpkht,z6G-z+p

md5.update(plainText.getBytes("utf-8"));

*UdS:sVlz#h {|0        byte[] digestBytes = md5.digest();

"zJ1|8C|T0        /*51Testing软件测试网YCuMkC8]/q#l

* 用私钥进行签名 RSA51Testing软件测试网&n F%wi0]m#p.M+~

* Cipher负责完成加密或解密,基于RSA51Testing软件测试网_4U$USL(y)x

*/51Testing软件测试网(T~ Q0Z&xr

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

m.gn)y%n5[0        //ENCRYPT_MODE表示为加密模式

A-z9p Tis0        cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(path, password));

l)N{'{`x1N0        //加密

WkFw.Z }D8`0        byte[] rsaBytes = cipher.doFinal(digestBytes);51Testing软件测试网,tXF9d'l#T/eQQv

//Base64编码51Testing软件测试网 q }-[~)~C(lBj

return Base64.byteArrayToBase64(rsaBytes);51Testing软件测试网%S;ve#Lz+[

3、B收到数据后,需要使用A提供的公钥信息进行验签,此处使用公钥的N、E进行验签

VNbE{4}5le.Fd|0首先通过公钥N、E得到公钥PublicKey,如下:Kk(d$zB:S(w051Testing软件测试网;wI$EeW7ka.M

51Testing软件测试网3D"Z9^*Kt?/**

*xRj*jmHO0     * 根据公钥n、e生成公钥

'Fo3i \DR#e0     * @param modulus   公钥n串51Testing软件测试网[8XBq

R

* @param publicExponent  公钥e串

]G#G9PNXiiL0     * @return 返回公钥PublicKey51Testing软件测试网`}[C&YV4i"E

* @throws Exception51Testing软件测试网0Wo7Cz1ip+`F

*/

k@h)I7\$O*{I[0    public static PublicKey getPublickKey(String modulus, String publicExponent)51Testing软件测试网Y)Ip.?`

throws Exception {

ja6M6g/DA`:nW0        KeySpec publicKeySpec = new RSAPublicKeySpec(

kER[oZ"z0                new BigInteger(modulus, 16), new BigInteger(publicExponent, 16));51Testing软件测试网&FlkC"_

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

ze1Z_n9F6QR\.A0        PublicKey publicKey = factory.generatePublic(publicKeySpec);

!`p9Mf!B&}j0        return publicKey;51Testing软件测试网QO},o&]2l8W

}51Testing软件测试网r`3JcM

得到公钥PublicKey后,再去验证签名,代码如下:51Testing软件测试网2]Hb3a/E/XRZ51Testing软件测试网5irn5zKvV6bm(]

51Testing软件测试网U9EVz'nbrk/**

n8yd+{(nTC0     * 用公钥证书进行验签

0F/F+xl(z0a u0     * @param message  签名之前的原文

i,~w%l{*?,J0     * @param cipherText  签名51Testing软件测试网Qlf}lP5M)iE

* @param pubKeyn 公钥n串51Testing软件测试网"ik;v_*l-O!q(D%h

* @param pubKeye 公钥e串51Testing软件测试网Ye8^9S)K

* @return boolean 验签成功为true,失败为false

#T'?7o/x}-j%S0     * @throws Exception

d5`&K5RCP;C(xy0     */51Testing软件测试网GR#qIp0dAc px&n

public static boolean verify(String message, String cipherText,String pubKeyn,51Testing软件测试网 @?S?

E8SH

String pubKeye) throws Exception {

+Q#}%z(t8X3Pv/e-A0        Cipher c4 = Cipher.getInstance("RSA/ECB/PKCS1Padding");

'n-iK ?+m)x0        // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示解密模式

]C*u?8jfLNd`Rpo0        c4.init(Cipher.DECRYPT_MODE, getPublickKey(pubKeyn,pubKeye));

(y)]tC9A5\0        // 解密

,t8[0cd[Km0        byte[] desDecTextBytes = c4.doFinal(Base64.base64ToByteArray(cipherText));51Testing软件测试网1txqWnc2z*GK:^

// 得到前置对原文进行的MD551Testing软件测试网*j6wwC8MiQ3R

String md5Digest1 = Base64.byteArrayToBase64(desDecTextBytes);

S;_ HVEt+v0        MessageDigest md5 = MessageDigest.getInstance("MD5");51Testing软件测试网:U'qku&[/ze ]w#^W

md5.update(message.getBytes("utf-8"));

(E{6n&y$Q@W-pD0        byte[] digestBytes = md5.digest();51Testing软件测试网)U;FO|PPEoN

// 得到商户对原文进行的MD551Testing软件测试网[0Ra&P;I,a*DLl

String md5Digest2 = Base64.byteArrayToBase64(digestBytes);51Testing软件测试网.C2N0W*y6p\

// 验证签名

$x4de&urYg0        if (md5Digest1.equals(md5Digest2)) {51Testing软件测试网"S2sA6pySm-J

return true;51Testing软件测试网.KL*e;iv)^AaXd

} else {

0B0^:Vwj1t5P0            return false;

Jw%JkY"B0        }

mnz]BQ-[~0    }51Testing软件测试网~{0NJ[ TpL

至此,签名验签已经完毕&F-z0d'm{MD6j0

Xg:Devay04、提供一个从.cer文件读取公钥的方法:51Testing软件测试网P*i:M;V#fj

5?*w

Y\,Jc051Testing软件测试网vpyR{5j/**

"B8Y{5v3YFR0     * 读取公钥cer

H_H%{Ou ws0     * @param path .cer文件的路径  如:c:/abc.cer

sJ?[_^#F{0     * @return  base64后的公钥串

f-`ycl0     * @throws IOException51Testing软件测试网VFTqJ!\x*|

* @throws CertificateException

AgO#U-N,S.P0     */

Y^7@0lj["M

LL0    public static String getPublicKey(String path) throws IOException,

a/m4a)d

Q1d|9P~ R0    CertificateException{51Testing软件测试网?V)z,t+N$iV

InputStream inStream = new FileInputStream(path);51Testing软件测试网)C$?ecf

ByteArrayOutputStream ut = new ByteArrayOutputStream();

!z}7\Q/K"k.]x0        int ch;

:y\{4|%Y*\A6nM0        String res = "";51Testing软件测试网D3[3U^prB

while ((ch = inStream.read()) != -1) {

(`g?gU0            out.write(ch);

NQs`8_/\'s0        }

.\-~&VOB

@b(C[G0        byte[] result = out.toByteArray();

X$r.qhNfWHz3D0        res = Base64.byteArrayToBase64(result);51Testing软件测试网9\F?ju

return res;

D#s/ZU8f\ny0    }

&T$Y'oj!o#m;r:Q0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值