JAVA加解密18-數(shù)字簽名算法RSA

一、概述
1.數(shù)字簽名算法可以看做是一個(gè)帶有密鑰的消息摘要算法切心,并且這個(gè)密鑰包括了公鑰和私鑰朽寞。他是非對(duì)稱加密算法和消息摘要算法的結(jié)合體
2.數(shù)字簽名算法是公鑰基礎(chǔ)設(shè)施(PKI)挂洛,以及許多網(wǎng)絡(luò)安全機(jī)制的基礎(chǔ)
3.數(shù)字簽名算法有抗否認(rèn)的作用
4.遵循“私鑰簽名,公鑰驗(yàn)證”規(guī)則
5.常見的數(shù)字簽名算法有RSA/DSA/ECDSA
6.java6支持實(shí)現(xiàn)了DSA算法超营、部分RSA算法需要bouncycastle支持鸳玩,最牛的ECDSA算法(微軟用來做操作系統(tǒng)序列號(hào)的那個(gè))完全需要Bouncycastle支持
二、模型分析
1.甲方構(gòu)造密鑰對(duì)(公鑰+私鑰)演闭,公布公鑰給乙方
2.甲方使用私鑰對(duì)數(shù)據(jù)進(jìn)行簽名不跟,然后將“簽名+數(shù)據(jù)” 發(fā)送給乙方
3.乙方使用公鑰+數(shù)字簽名 驗(yàn)證數(shù)據(jù)

三、代碼分析

package com.ca.test;
import java.security.Key;
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.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;

/**
 * 經(jīng)典的數(shù)字簽名算法RSA
 * 數(shù)字簽名
 * @author kongqz
 * */
public class RSACoder {
    //數(shù)字簽名米碰,密鑰算法
    public static final String KEY_ALGORITHM="RSA";
    
    /**
     * 數(shù)字簽名
     * 簽名/驗(yàn)證算法
     * */
    public static final String SIGNATURE_ALGORITHM="MD5withRSA";
    
    /**
     * RSA密鑰長度窝革,RSA算法的默認(rèn)密鑰長度是1024
     * 密鑰長度必須是64的倍數(shù),在512到65536位之間
     * */
    private static final int KEY_SIZE=512;
    //公鑰
    private static final String PUBLIC_KEY="RSAPublicKey";
    
    //私鑰
    private static final String PRIVATE_KEY="RSAPrivateKey";
    
    /**
     * 初始化密鑰對(duì)
     * @return Map 甲方密鑰的Map
     * */
    public static Map<String,Object> initKey() throws Exception{
        //實(shí)例化密鑰生成器
        KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(KEY_ALGORITHM);
        //初始化密鑰生成器
        keyPairGenerator.initialize(KEY_SIZE);
        //生成密鑰對(duì)
        KeyPair keyPair=keyPairGenerator.generateKeyPair();
        //甲方公鑰
        RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();
        //甲方私鑰
        RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();
        //將密鑰存儲(chǔ)在map中
        Map<String,Object> keyMap=new HashMap<String,Object>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
        
    }
    
    
    /**
     * 簽名
     * @param data待簽名數(shù)據(jù)
     * @param privateKey 密鑰
     * @return byte[] 數(shù)字簽名
     * */
    public static byte[] sign(byte[] data,byte[] privateKey) throws Exception{
        
        //取得私鑰
        PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(privateKey);
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //生成私鑰
        PrivateKey priKey=keyFactory.generatePrivate(pkcs8KeySpec);
        //實(shí)例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initSign(priKey);
        //更新
        signature.update(data);
        return signature.sign();
    }
    /**
     * 校驗(yàn)數(shù)字簽名
     * @param data 待校驗(yàn)數(shù)據(jù)
     * @param publicKey 公鑰
     * @param sign 數(shù)字簽名
     * @return boolean 校驗(yàn)成功返回true见间,失敗返回false
     * */
    public static boolean verify(byte[] data,byte[] publicKey,byte[] sign) throws Exception{
        //轉(zhuǎn)換公鑰材料
        //實(shí)例化密鑰工廠
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公鑰
        //密鑰材料轉(zhuǎn)換
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(publicKey);
        //產(chǎn)生公鑰
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);
        //實(shí)例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initVerify(pubKey);
        //更新
        signature.update(data);
        //驗(yàn)證
        return signature.verify(sign);
    }
    /**
     * 取得私鑰
     * @param keyMap 密鑰map
     * @return byte[] 私鑰
     * */
    public static byte[] getPrivateKey(Map<String,Object> keyMap){
        Key key=(Key)keyMap.get(PRIVATE_KEY);
        return key.getEncoded();
    }
    /**
     * 取得公鑰
     * @param keyMap 密鑰map
     * @return byte[] 公鑰
     * */
    public static byte[] getPublicKey(Map<String,Object> keyMap) throws Exception{
        Key key=(Key) keyMap.get(PUBLIC_KEY);
        return key.getEncoded();
    }
    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        //初始化密鑰
        //生成密鑰對(duì)
        Map<String,Object> keyMap=RSACoder.initKey();
        //公鑰
        byte[] publicKey=RSACoder.getPublicKey(keyMap);
        
        //私鑰
        byte[] privateKey=RSACoder.getPrivateKey(keyMap);
        System.out.println("公鑰:/n"+Base64.encodeBase64String(publicKey));
        System.out.println("私鑰:/n"+Base64.encodeBase64String(privateKey));
        
        System.out.println("================密鑰對(duì)構(gòu)造完畢,甲方將公鑰公布給乙方聊闯,開始進(jìn)行加密數(shù)據(jù)的傳輸=============");
        String str="RSA數(shù)字簽名算法";
        System.out.println("原文:"+str);
        //甲方進(jìn)行數(shù)據(jù)的加密
        byte[] sign=RSACoder.sign(str.getBytes(), privateKey);
        System.out.println("產(chǎn)生簽名:"+Base64.encodeBase64String(sign));
        //驗(yàn)證簽名
        boolean status=RSACoder.verify(str.getBytes(), publicKey, sign);
        System.out.println("狀態(tài):"+status+"/n/n");
        
        
    }
}
控制臺(tái)輸出:
公鑰:
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJXmcnNTaWUnib5uMMQI2VCAq/rCPoFonlGHBVhDatRH
GLEkZ2z/PiT1RxrmBdRxAb50LoNYGUOvOCieOJqU4B8CAwEAAQ==
私鑰:
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAleZyc1NpZSeJvm4wxAjZUICr+sI+
gWieUYcFWENq1EcYsSRnbP8+JPVHGuYF1HEBvnQug1gZQ684KJ44mpTgHwIDAQABAkBUaU3f5YO/
Q7GMe+6YJceCTsMJ1WJvayNkE52N44EAAhkfmbpmhwdcRgo0CnzAsiXdPeB1inynbnv1ornu/AlZ
AiEA/iTqVvxeYFjaYfvi38OxfNNeqpBMiPjv3XlYzEs4vR0CIQCW/qm+3Lv9YpLlqWGipBBrHGfu
yv4spXxiY/mkbh4ZawIhAO14JvOSqsjSHXSS/WHipFSj2H/9h1YxbUf/3AZAf0rNAiA88cTpuIZY
G3VXJSq3Tqkh0nFQvLYipxixTdDxQVD8yQIhAIgXKKDfKeEXdmx3untvAo1zh3//MhVoo3JygBsR
gSYn
================密鑰對(duì)構(gòu)造完畢,甲方將公鑰公布給乙方,開始進(jìn)行加密數(shù)據(jù)的傳輸=============
原文:RSA數(shù)字簽名算法
產(chǎn)生簽名:dxlBzv3voS7YDaaNCrUaIw7ITfHHDrdfwry9d5gSbMhKPWWfBecx0jA8jPmRuYQW2iViCDHUs3n7
Smu3VZDuZw==
狀態(tài):true

四米诉、總結(jié)
1.簽名算法對(duì)非對(duì)稱加密算法RSA的公鑰私鑰的使用是核心,配合信息摘要算法完成簽名操作篷帅。其實(shí)簽名看起來就是信息的摘要而已
2.密鑰處理方面和非對(duì)稱加密算法無異史侣,只是將加密、解密換成簽名魏身、驗(yàn)證
3.RSA的數(shù)字簽名算法的密鑰實(shí)現(xiàn)與RSA加密算法一致惊橱。所以簽名算法可以分為MD系列和SHA系列

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市箭昵,隨后出現(xiàn)的幾起案子税朴,更是在濱河造成了極大的恐慌,老刑警劉巖家制,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件正林,死亡現(xiàn)場離奇詭異,居然都是意外死亡颤殴,警方通過查閱死者的電腦和手機(jī)觅廓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涵但,“玉大人杈绸,你說我怎么就攤上這事“粒” “怎么了瞳脓?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澈侠。 經(jīng)常有香客問我劫侧,道長,這世上最難降的妖魔是什么埋涧? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任板辽,我火速辦了婚禮奇瘦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘劲弦。我一直安慰自己耳标,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布邑跪。 她就那樣靜靜地躺著次坡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪画畅。 梳的紋絲不亂的頭發(fā)上砸琅,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音轴踱,去河邊找鬼症脂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛淫僻,可吹牛的內(nèi)容都是我干的诱篷。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼雳灵,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼棕所!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悯辙,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤琳省,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后躲撰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體针贬,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年茴肥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坚踩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓤狐,死狀恐怖瞬铸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情础锐,我是刑警寧澤嗓节,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站皆警,受9級(jí)特大地震影響拦宣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一鸵隧、第九天 我趴在偏房一處隱蔽的房頂上張望绸罗。 院中可真熱鬧,春花似錦豆瘫、人聲如沸珊蟀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽育灸。三九已至,卻和暖如春昵宇,著一層夾襖步出監(jiān)牢的瞬間磅崭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工瓦哎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砸喻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓蒋譬,卻偏偏與公主長得像恩够,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羡铲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 隨著對(duì)于安全度的不斷要求腰湾,對(duì)于數(shù)據(jù)加解密與破解之間的斗爭雷恃,加解密的方式也在不斷發(fā)生著變化,來看看現(xiàn)在流行的一些加解...
    zhouhao_180閱讀 2,076評(píng)論 1 12
  • 本文主要介紹移動(dòng)端的加解密算法的分類费坊、其優(yōu)缺點(diǎn)特性及應(yīng)用倒槐,幫助讀者由淺入深地了解和選擇加解密算法。文中會(huì)包含算法的...
    蘋果粉閱讀 11,480評(píng)論 5 29
  • 在開發(fā)應(yīng)用過程中附井,客戶端與服務(wù)端經(jīng)常需要進(jìn)行數(shù)據(jù)傳輸讨越,涉及到重要隱私安全信息時(shí),開發(fā)者自然會(huì)想到對(duì)其進(jìn)行加密永毅,即使...
    閑庭閱讀 3,262評(píng)論 0 11
  • 在蘋果全球開發(fā)者大會(huì)上沼死,蘋果規(guī)定2017年1月1日以后着逐,App Store 當(dāng)中的所有應(yīng)用必須打開ATS(iOS9...
    Mariko00o閱讀 3,999評(píng)論 0 51
  • http://www.ctolib.com/open-source-android-apps.html這個(gè)是比較全...
    瘋子來過閱讀 464評(píng)論 0 1