1. 程式人生 > >RSA加解密,加簽以及驗籤。

RSA加解密,加簽以及驗籤。

由於RSA演算法是不對稱加密演算法,所以每次加密得到的資料都不相同,同理加簽得到的資料每次也不一樣。

簡單的說下不對稱演算法,就是兩把不同,但是完全匹配的祕鑰,去進行加解密,公鑰對外提供進行資料加密,私鑰自己儲存,對加密的資料進行解密。所以私鑰不要洩露。

RSA演算法原理:

1、任意互質的兩個質數p,q。

2、得到連個質數的乘積n。

3、得到兩個質數的歐元函式f(n)=(p-1) * (q-1)。

4、任取一個小於f(n)並與其互質的質數e。

5、存在一個數d,使得e^d % f(n) = 1。

6、則(n,e)為公鑰,(n,d)為私鑰。

加密:待加密資料t:

t^te% n = m(m為加密後的資料);

解密:m^d % n = t(t為原資料)

Java實現RSA演算法加密解密,加簽以及驗籤程式碼如下:

1、Base64工具類:

//Base64加密public static String encryptBase64(byte[] key){
    return new String(Base64.encodeBase64(key));
}

//Base64解密
public static byte[] decryptBase64(String key) throws IOException {
    return new BASE64Decoder().decodeBuffer(key);
}

2、獲取RSA祕鑰對:

public static Map<String, Object> keyMap()throws Exception{
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    PublicKey publicKey = keyPair.getPublic();
    PrivateKey privateKey = keyPair.getPrivate();

    Map<String, Object> keyMap = new 
HashMap<>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; }
3、獲取RSA公鑰以及私鑰分別儲存到檔案中:
public static void keyToFile(Map keymap)throws Exception{
    PublicKey publicKey = (PublicKey) keymap.get(PUBLIC_KEY);
    PrivateKey privateKey = (PrivateKey)keymap.get(PRIVATE_KEY);
    String encryptBase64PublicKey = encryptBase64(publicKey.getEncoded());
    String encryptBase64PrivateKey = encryptBase64(privateKey.getEncoded());
    FileWriter fw = new FileWriter("src/main/resources/pubKey.txt");//按需要儲存路徑,下同
    FileWriter fw1 = new FileWriter("src/main/resources/priKey.txt");
    fw.write(encryptBase64PublicKey);
    fw.flush();
    fw.close();
    fw1.write(encryptBase64PrivateKey);
    fw1.flush();
    fw1.close();
}
4、從檔案中獲取公鑰:
public static RSAPublicKey getPublicKeyForFile() throws Exception {
    File file = new File("src/main/resources/pubKey.txt");

    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    String readLine = null;
    StringBuffer sb = new StringBuffer();
    while ((readLine = br.readLine()) != null) {
        sb.append(readLine);
    }
    String publicKeyStr = sb.toString();
    System.out.println("從檔案獲取到的公鑰:" + publicKeyStr);
    //Base64解密
byte[] decryptBase64 = GetKey.decryptBase64(publicKeyStr);
    //選取金鑰編碼規則
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decryptBase64);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPublicKey rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
    return rsaPublicKey;
}

5、從檔案中獲取私鑰:

//從檔案中獲取私鑰
public static RSAPrivateKey getPrivateKeyForFile() throws Exception {
    FileInputStream fis = new FileInputStream("src/main/resources/priKey.keyStore");
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    String readLine = null;
    StringBuffer sb = new StringBuffer();
    while ((readLine = br.readLine()) != null) {
        sb.append(readLine);
    }
    String privateKey = sb.toString();
    System.out.println("從檔案獲取到的私鑰:" + privateKey);
    //Base64解密
byte[] bytes = GetKey.decryptBase64(privateKey);
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    return rsaPrivateKey;
}

6.公鑰加密/私鑰解密:

public static byte[] encryptOrDecrypt(Key key, byte[] data, int mode) throws Exception {
    //加密演算法:RSA/ECB/PKCS1Padding
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    //提供者
    Provider provider = new BouncyCastleProvider();
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
    cipher.init(mode, key);
    int blockSize = cipher.getBlockSize();
    int length = data.length;
    int num = length / blockSize + 1;
    int cache = blockSize;
    byte[] bytes = null;
    for (int i = 0; i < num; i++) {
        if (i == num - 1) {
            cache = length % blockSize;
            if (cache == 0) {
                return out.toByteArray();
            }
        }
        bytes = cipher.doFinal(data, i * blockSize, cache);
        out.write(bytes);
    }
    return out.toByteArray();
}
7.RSA私鑰加簽:
 public static String addSign(PrivateKey privateKey, String context)throws Exception{        //加簽演算法:SHA1WithRSA
Signature signature = Signature.getInstance("SHA1WithRSA");
        signature.initSign(privateKey);
        signature.update(context.getBytes("utf-8"));
        byte[] sign = signature.sign();
        return encryptBase64(sign);
    }
8.RSA公鑰驗籤:
public static boolean verifySign(PublicKey publicKey, String context, String signData)throws Exception{Signature signature = Signature.getInstance("SHA1WithRSA");
        signature.initVerify(publicKey);
        byte[] bytes = decryptBase64(signData);
        signature.update(context.getBytes("utf-8"));
        boolean verify = signature.verify(bytes);
        return verify;
    }
9.主測試類:
public class Sign {
  private final static String PUBLIC_KEY = "PUBLIC_KEY";
  private final static String PRIVATE_KEY = "PRIVATE_KEY";
public static void main(String[] args) { try {
Map<String, Object> map = keyMap();
keyToFile(map);
RSAPublicKey rsaPublicKey = getPublicKeyForFile();
System.out.println("rsaPublicKey公鑰是:" + rsaPublicKey);
RSAPrivateKey rsaPrivateKey = getPrivateKeyForFile();
System.out.println("rsaPublicKey私鑰是:" + rsaPrivateKey);
String data = "這是一個加密字串"
//加密
byte[] encrypt = encryptOrDecrypt(rsaPublicKey, data.getBytes("utf-8"), Cipher.ENCRYPT_MODE);
String s = encryptBase64(encrypt);
System.out.println("加密後的資料:" + s);
//解密byte[] decrypt = encryptOrDecrypt(rsaPrivateKey, decryptBase64(s), Cipher.DECRYPT_MODE);System.out.println("解密後的資料" + new String(decrypt));
//加簽
String signData = addSign(rsaPrivateKey, data);
System.out.println("加簽後的資料:" + signData);
//驗籤
boolean b = verifySign(rsaPublicKey, data, signData);
System.out.println("驗簽得到的布林值為:" + b);
 } catch (Exception e) {
        e.printStackTrace();
    }
}
最後要說明的是要匯入這個包:
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk16</artifactId>
    <version>1.46</version>
</dependency>

相關推薦

RSA解密以及

由於RSA演算法是不對稱加密演算法,所以每次加密得到的資料都不相同,同理加簽得到的資料每次也不一樣。 簡單的說下不對稱演算法,就是兩把不同,但是完全匹配的祕鑰,去進行加解密,公鑰對外提供進行資料加密,私鑰自己儲存,對加密的資料進行解密。所以私鑰不要洩露。 RSA演算法原理:

C# RSA加密、解密、支援JAVA格式公鑰私鑰、PEM格式公鑰私鑰、.NET格式公鑰私鑰 -變態模式【支援私鑰加密公鑰解密】(二)

RSA變態模式:【私鑰加密,公鑰解密】 一般這種寫法都是JAVA弄的。.NET原生不支援。為啥,我也不清楚,大概是因為安全性問題吧,畢竟公鑰是人人都可是持有的。私鑰只有自己擁有。 簽名一直都是【私鑰加簽、公鑰驗籤】只為證明該訊息是你發出來的。 這裡使用了BouncyC

C# RSA加密、解密、支援JAVA格式公鑰私鑰、PEM格式公鑰私鑰、.NET格式公鑰私鑰、一般模式【支援公鑰加密私鑰解密】(一)

2017-12-04日更新:增加支援微信支付。程式碼註釋中//☆☆☆☆.NET 4.6以後特有☆☆☆☆的別用,那個不對。 RSA非對稱加密。簡明扼要吧,直說乾貨。(在此特別感謝下貳進位制,提供JAVA版的公鑰私鑰) C#RSA加簽解籤加密比較常見,一般遇到的問題是非.NET

iOS和java之間的RSA加密解密認證對接

對接場景: 伺服器端使用java生成公鑰和私鑰,將公鑰傳遞給iOS加密 or 將私鑰傳遞給iOS端使用openssl進行簽名,然後在伺服器端進行驗證 java端: 1、使用常規的KeyPairGenerator類生成公鑰和私鑰 KeyPairGenerator gen =

基於mbedtls-1.3.14庫的rsa公鑰與私鑰生成與解密base64編碼與解碼用法介紹

1.1 之前總結了一篇關於AES加密與解密,base64編碼與解碼用法介紹,順便把rsa的用法也總結一下 1.2 用法 #incl

AES解密相容win和linux平臺

AES加密 此文采用對稱加密演算法-AES,所謂對稱是說傳送方和接收方的金鑰是一樣的。 據說實現該演算法的時候,設定金鑰長度大於128會出現錯誤:Illegal key size or default parameters,這是因為美國的出口限制,Sun通過許可權檔案(local_polic

軟實現非對稱解密公鑰證書與公鑰值區別包含提取公約值程式碼

目前有部分未採購簽名驗籤伺服器的企業,採用軟實現做非對稱、對稱加解密,本文簡略說明一下工作過程中遇到的問題。 本交易涉及傳送方,接收方 問題背景: 對方即接收方採用的是軟實現,並且只提供了公鑰值(未經CA簽發) 我方即傳送方,採用的是硬體簽名驗籤服務。伺服器中存有我方的私鑰,

python實現aes加密解密RSA簽名和RSA加密解密並呼叫介面

用python實現呼叫介面的示例程式碼,過程涉及到很多的加密演算法,值得分享一下。首先公鑰和私鑰如何生成,並且能相容java平臺,嘗試了很多方法。最終決定用openssl命令前提,需要安裝openssl,Crypto庫生成公鑰私鑰對過程:生成私鑰: openssl ge

解密對稱與非對稱 簽名 數字證書原理

文中首先解釋了加密解密的一些基礎知識和概念,然後通過一個加密通訊過程的例子說明了加密演算法的作用,以及數字證書的出現所起的作用。接著對數字證書做一個詳細的解釋,並討論一下windows中數字證書的管理,最後演示使用makecert生成數字證書。如果發現文中有錯誤的地方,或

3Des解密壓縮檔案

import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey;

非對稱解密私鑰和公鑰到底是誰來加密誰來解密

第一種用法:公鑰加密,私鑰解密。---用於加解密 第二種用法:私鑰簽名,公鑰驗籤。---用於簽名 有點混亂,不要去硬記,總結一下: 你只要想: 既然是加密,那肯定是不希望別人知道我的訊息,所以只有我才能

flask(十)使用alembic進行數據庫結構管理升級

pan bsp 工作 group 數據 none 如果 找到 ask 1.安裝擴展,在虛擬環境中安裝 alembic,不懂可以去看pycharm的系列文章。 2.初始化, 使用 Alembic 前需要通過 alembic init 命令創建一個 alembic 項目,該命令

php+js 防止被抓包篡改資料資料名校

簽名金鑰,這個是自己生成的,需要客戶端+服務端一致。 <?php /** * 獲取簽名 * @param $data 提交的資料 * @param $key 安全金鑰 * @return bool */ function signature($data, $key) {

Python下RSA加密/解密 簽名/

import rsa # 生成金鑰 (pubkey, privkey) = rsa.newkeys(1024) # 儲存金鑰 with open('public.pem','w+') as f: f.write(pubkey.save_pkcs1().de

Python 給圖片文字圖片水印

1. 加文字from PIL import Image, ImageDraw, ImageFont # 指定要使用的字型和大小;/Library/Fonts/是macOS字型目錄;Linux的字型目錄是/usr/share/fonts/ font = ImageFont

Spring 介面資料解密---全域性解密

Spring 介面資料加解密—全域性加解密篇 資料加密傳輸 加解密處理 自定義message-converters 小結 資料加密傳輸 企業級開發,是缺少不了資料的加密傳輸。如若不是,請自重。微信公共號的開發便提供AES加密處理,提高公共號的安全性

Latex設定字型大小下劃線變斜體

Latex 設定字型大小命令由小到大依次為:\tiny\scriptsize\footnotesize\small\normalsize\large\Large\LARGE\huge\Huge使用方法,例如:\large{這是大號字型}  加粗:\textbf{文字}數學模式

RSA加密解密String轉PublicKey、PrivateKey;附Base64.JAR

網路請求的資料需要加密,伺服器給的他們那一套在Android一直報錯,自己寫了一個;package com.cc.common.util; import javax.crypto.Cipher; import java.security.*; import java.se

數組中的filter函數遞歸以及一些應用

都沒有 name 返回 。。 filter 簡單 where 忽略 ldr 當我們用一個東西時候我們必須知道的是?why---where----how---when。一個東西我們為什麽用?在哪用?怎麽用?何時用?而不是被動的去接受一些東西。用在js裏邊我覺得也會試用。一直追

Springboot框架實現請求資料解密響應資料加密的功能

一、簡要說明:   在做這個功能的時候,參考了很多文章,也試了用過濾器解決。但總體來說還是很麻煩,所以換了另一種解決方案。直接實現RequestBodyAdvice和ResponseBodyAdvice兩個介面 ,進行加密解密處理。   關於RequestBodyAdvice和ResponseBodyAd