日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

RSA签名算法 - Java加密与安全

發(fā)布時(shí)間:2024/4/13 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RSA签名算法 - Java加密与安全 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

RSA簽名算法在非對(duì)稱加密中我們可以看到,甲乙雙方要進(jìn)行通信,用publicKey進(jìn)行加密,用priavteKey解密,這個(gè)時(shí)候會(huì)出現(xiàn)一個(gè)問(wèn)題,如果黑客用你的publicKey對(duì)消息進(jìn)行加密,然后冒充甲發(fā)送給乙,乙怎么確定這個(gè)消息是甲發(fā)送,還是有人偽造甲發(fā)送的呢,所以我們就需要數(shù)字簽證算法,發(fā)送加密消息的時(shí)候同時(shí)需要發(fā)送簽名,而這個(gè)簽名是需要甲的privateKey計(jì)算的,而乙要驗(yàn)證這個(gè)簽名,是否是合法的,它會(huì)用甲的publicKey進(jìn)行驗(yàn)證,如果驗(yàn)證成功,證明這個(gè)消息確實(shí)是甲發(fā)送的

數(shù)字簽名就是發(fā)送方用自己的私鑰對(duì)消息進(jìn)行簽名,然后接受方用發(fā)送方的私鑰來(lái)驗(yàn)證簽名是否有效,我們可以把數(shù)字簽名混入了公鑰和私鑰的一種摘要,publicKey和原始簽名和message著三個(gè)中的任何一個(gè)被修改了,簽名都是無(wú)效的數(shù)字簽名的目的是:1. 確認(rèn)信息是某個(gè)發(fā)送方發(fā)送的,因?yàn)橹挥兴米约旱膒rivateKey簽名,其他人才能用它的publicKey去驗(yàn)證這個(gè)簽名2. 發(fā)送方還不能抵賴他發(fā)送了消息,因?yàn)橛谜l(shuí)的publicKey成功驗(yàn)證的簽名,就一定是誰(shuí)用privateKey簽名的,所以privateKey就相當(dāng)于用戶的身份3. 最后數(shù)字簽名保證在傳輸過(guò)程中沒(méi)有被修改常用的數(shù)字簽名算法有:1. MD5WithRSA2. SHA1WithRSA3. SHA256WithRSA package com.learn.securl;import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64;/*** 使用RSA簽名算法的時(shí)候* 我們同樣要生成privateKey和publicKey* @author Leon.Sun**/ public class SecRSASignature {PrivateKey sk;PublicKey pk;/*** 生成公鑰/私鑰對(duì)* @throws GeneralSecurityException*/public SecRSASignature() throws GeneralSecurityException{/*** 生成KeyPair的方法和使用RSA加密是一樣的*/KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");kpGen.initialize(1024);KeyPair kp = kpGen.generateKeyPair();this.sk = kp.getPrivate();this.pk = kp.getPublic();}/*** 從以保存的字節(jié)中(例如:讀取文件)恢復(fù)公鑰/私鑰* @param pk* @param sk* @throws GeneralSecurityException*/public SecRSASignature(byte[] pk, byte[] sk) throws GeneralSecurityException{KeyFactory kf = KeyFactory.getInstance("RSA");X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pk);this.pk = kf.generatePublic(pkSpec);PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(sk);this.sk = kf.generatePrivate(skSpec);}/*** 把私鑰導(dǎo)出為字節(jié)* @return*/public byte[] getProvateKey(){return this.sk.getEncoded();}/*** 把公鑰導(dǎo)出為字節(jié)* @return*/public byte[] getPublicKey(){return this.pk.getEncoded();}/*** sign by sk* 然后我們定義一個(gè)sign方法* 用于對(duì)數(shù)據(jù)進(jìn)行簽名* 當(dāng)我們使用簽名算法的時(shí)候* @param message* @return* @throws GeneralSecurityException*/public byte[] sign(byte[] message) throws GeneralSecurityException{/*** 我們首先通過(guò)Signature.getInstance* 然后傳入簽名算法的算法名稱* 這里我們使用SHA1withRSA* 我們就得到一個(gè)Signature對(duì)象*/Signature signature = Signature.getInstance("SHA1withRSA");/*** 然后我們調(diào)用initSign* 傳入我們的privateKey* 初始化一個(gè)簽名*/signature.initSign(this.sk);/*** 緊接著我們用update方法傳入一個(gè)消息* 表示這個(gè)消息進(jìn)行簽名*/signature.update(message);/*** 接著我們用signature的sign方法* 就可以獲得簽名以后的字節(jié)*/return signature.sign();}/*** sign by pk* 我們?cè)俣x一個(gè)verify方法來(lái)驗(yàn)證簽名* 驗(yàn)證簽名的時(shí)候* 我們需要傳入原始信息和簽名信息* @param message* @param sign* @return* @throws GeneralSecurityException*/public boolean verify(byte[] message, byte[] sign) throws GeneralSecurityException{/*** 同樣我們調(diào)用Signature.getInstance* 然后傳入SHA1withRSA* 獲得一個(gè)Signature對(duì)象*/Signature signature = Signature.getInstance("SHA1withRSA");/*** 這個(gè)時(shí)候我們要調(diào)用initVerify* 然后傳入publicKey* 表示我們要驗(yàn)證的簽名* 驗(yàn)證簽名只能使用publicKey*/signature.initVerify(this.pk);/*** 然后我們傳入原始的信息*/signature.update(message);/*** 最后我們調(diào)用verigy并傳入簽名信息* 表示對(duì)簽名進(jìn)行驗(yàn)證* 簽名的結(jié)果為true或者false*/return signature.verify(sign);}/*** 現(xiàn)在我們用main來(lái)對(duì)RSA簽名進(jìn)行測(cè)試* @param args* @throws Exception*/public static void main(String[] args) throws Exception{byte[] message = "Hello, 使用SHA1withRSA算法進(jìn)行數(shù)字簽名!".getBytes();SecRSASignature rsas = new SecRSASignature();/*** 我們首先通過(guò)sign方法對(duì)信息進(jìn)行簽名*/byte[] sign = rsas.sign(message);/*** 然后打印出簽名的結(jié)果*/System.out.println("sign: " + Base64.getEncoder().encodeToString(sign));/*** 然后我們通過(guò)verify方法對(duì)信息和簽名進(jìn)行驗(yàn)證*/boolean verified = rsas.verify(message, sign);/*** 然后打印出簽名的結(jié)果* * verify: true* 我們用原始的公鑰進(jìn)行的簽名結(jié)果為true,*/System.out.println("verify: " + verified);// 用另一個(gè)公鑰驗(yàn)證:/*** 如果我們創(chuàng)建另一個(gè)Signature對(duì)象* 然后用另一個(gè)公鑰去驗(yàn)證*/boolean verified2 = new SecRSASignature().verify(message, sign);/*** 我們可以看到驗(yàn)證的結(jié)果為false* * verify with another public key: false* 我們用另一個(gè)publicKey進(jìn)行的簽名結(jié)果為false*/System.out.println("verify with another public key: " + verified2);// 修改原始信息:/*** 當(dāng)我們把原始信息修改為一個(gè)字節(jié)的時(shí)候*/message[0] = 100;/*** 我們?cè)賹?duì)信息和簽名進(jìn)行驗(yàn)證* 我們可以看到改正過(guò)的信息驗(yàn)證的結(jié)果也應(yīng)該為false* * verify changed message: false* 我們對(duì)原始信息進(jìn)行的改動(dòng)結(jié)果為false*/boolean verified3 = rsas.verify(message, sign);System.out.println("verify changed message: " + verified3);} } 現(xiàn)在我們總結(jié)一下:1. 數(shù)字前面就是用發(fā)送方的私鑰對(duì)原始數(shù)據(jù)進(jìn)行簽名2. 只有用發(fā)送方的公鑰才能通過(guò)簽名驗(yàn)證,這樣做的目的是為了防止偽造發(fā)送方,防止抵賴發(fā)送過(guò)信息,防止發(fā)送信息發(fā)送過(guò)程中被修改3. 常用的算法有:MD5withRSA,SHA1withRSA,SHA256withRSA

?

總結(jié)

以上是生活随笔為你收集整理的RSA签名算法 - Java加密与安全的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。