亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

eclipse實現(xiàn)Schnorr數(shù)字簽名

 更新時間:2020年09月01日 15:51:22   作者:禿頭選拔賽形象大使  
這篇文章主要為大家詳細介紹了eclipse實現(xiàn)Schnorr數(shù)字簽名,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

Schnorr數(shù)字簽名,供大家參考,具體內(nèi)容如下

一、實驗?zāi)康?/strong>

學(xué)習(xí)Schnorr算法在數(shù)字簽名方面的使用,掌握公鑰簽名中最基礎(chǔ)的簽名算法-Schnorr數(shù)字簽名算法的編寫。

二、實驗要求

1. 熟悉Schnorr算法的描述,已經(jīng)其使用場景。
2. 熟悉Schnorr數(shù)字簽名算法。
3. 掌握如何使用java語言,實現(xiàn)Schnorr簽名算法。

三、開發(fā)環(huán)境

JDK1.8,eclipse。

四、實驗原理

數(shù)字簽名是指消息發(fā)送方利用特定參數(shù)產(chǎn)生的一段消息碼,該消息碼可以用來標(biāo)識消息發(fā)送者真實身份,同時可以標(biāo)識發(fā)送的數(shù)據(jù)的完整性,所以在一定程度防止了發(fā)送的數(shù)據(jù)在發(fā)送過程中被攻擊者篡改的行為。簡而言之,數(shù)字簽名就是由消息發(fā)送者利用身份信息與消息相結(jié)合產(chǎn)生的一個消息摘要。

在數(shù)字簽名過程中核心的兩個步驟就是產(chǎn)生簽名信息和對簽名信息的驗證,產(chǎn)生簽名就是消息發(fā)送方使用特定的簽名算法將數(shù)據(jù)產(chǎn)生成消息摘要,同時使用私鑰對其摘要進行加密,最后將加密后的密文和原始的數(shù)據(jù)一起發(fā)送。消息接收方收到信息后,首先用發(fā)送者的公鑰來算數(shù)據(jù)的摘要,然后把此結(jié)果與收到的摘要對比,如果一致,則驗證通過,認為該消息是真實有效的。反之無效,丟棄該消息。過程如下圖1所示。

a) 數(shù)字簽名加密過程

b) 數(shù)字簽名解密驗證過程

圖1 數(shù)字簽名過程

Schnorr簽名算法是由德國數(shù)學(xué)家、密碼學(xué)家Claus Schnorr提出,是Elgamal簽名方案的變種。

具體步驟如下:

首先是生成公鑰/私鑰對,過程如下:

a. 選擇素數(shù) 和 ,其中 是 的素因子;
b. 選擇一個整數(shù) ,使得 ; 、 和 構(gòu)成全局公鑰參數(shù),在用戶組內(nèi)的每個用戶都可以使用;
c. 選擇隨機整數(shù) 作為用戶的私鑰,其中 ;
d. 計算公鑰 ;

對于密鑰對為 的用戶,通過以下過程產(chǎn)生簽名:

a. 選擇隨機整數(shù),計算 ;
b. 將 附在消息后面,一起計算Hash值 :

c. 計算。

簽名對為 ,其他用戶通過以為過程來驗證簽名:
a. 計算;
b. 驗證等式 是否成立。

代碼段:

SchnorrSignature

import java.io.File;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.List;

/**
 * @ClassName: SchnorrSignature
 * @date: 2020年6月16日 下午9:25:09
 * @Description:schnorr簽名
 */
public class SchnorrSignature {
 // 路徑前綴
 private static final String PERFIX_PATH = GetProjectPath.getPath() + "/ra/";
 // 存放公共參數(shù)
 private static final String PARAM_PATH = PERFIX_PATH + "initParams.properties";
 // 存放公鑰的路徑
 private static final String PUBLIC_KEY_PATH = PERFIX_PATH + "publicKey.properties";
 
 /**
 * @Description: 系統(tǒng)初始化階段,把初始化的密碼公共參數(shù)存放到文件中去
 * @param blq:選擇的q的bit長度
* @Date:下午9:28:20
 */
 public static void initPara(int blq) {
 File file = new File(PARAM_PATH);
 if(file.exists()) {
 System.out.println("已經(jīng)存在初始化參數(shù),為不影響已經(jīng)頒發(fā)的證書,如果你強制要重新產(chǎn)生參數(shù),請備份所有文件到其他路徑下,并重新生產(chǎn)密鑰對并重新簽名");
 }else {
 System.out.println("系統(tǒng)初始化中,生產(chǎn)公共參數(shù)... ...");
 BigInteger one = new BigInteger("1");
 BigInteger two = new BigInteger("2");
 BigInteger q, qp, p, a, g;
 int certainty = 100;
 SecureRandom sr = new SecureRandom();
 // blq長度的q, q是p-1的素因子 
 //生成BigInteger偽隨機數(shù),它可能是(概率不小于1 - 1/2certainty)一個具有指定 bitLength 的素數(shù)
 q = new BigInteger(blq, certainty, sr);
 qp = BigInteger.ONE;
 do { // 選擇一個素數(shù) p 
 p = q.multiply(qp).multiply(two).add(one);
 if(p.isProbablePrime(certainty))
 break;
 qp = qp.add(BigInteger.ONE);
 } while(true);
 
 while(true) {
 a = (two.add(new BigInteger(blq, 100, sr))).mod(p);// (2+x) mod p
 BigInteger ga = (p.subtract(BigInteger.ONE)).divide(q);// (p-1)/q
 g = a.modPow(ga, p); // a^ga mod p = 1 
 if(g.compareTo(BigInteger.ONE) != 0) // g!=1
 break;
 }
 // 存放公共參數(shù)
 List<String> transArryToLi = KeyPairOperate.transArryToLi(new String[] {"blq=" + blq,"q=" + q, "p=" + p, "g=" + g});
 KeyPairOperate.writePublicKeyToFile(PARAM_PATH, transArryToLi, false);
 System.out.println("...");
 System.out.println("初始化完成!");
 }
 }
 
 /**
 * @Description: 為用戶生成公私鑰對
 * @param user:傳入用戶的身份
 * @Return:void
 * @Date:上午9:32:18
 */
 public static void generateKeyForUser(String user) {
 File file = new File(PERFIX_PATH + user + ".properties");
 if(file.exists()) {
 System.out.println(user + "已經(jīng)頒發(fā)了密鑰,請備份所有文件到其他路徑下,并重新簽名");
 }else {
 System.out.println("密鑰頒發(fā)中,請稍后");
 System.out.println("... ...");
 BigInteger sk,pk;// 私鑰和公鑰
 int blq = Integer.parseInt(KeyPairOperate.getDataFromFile(PARAM_PATH, "blq"));
 SecureRandom sr = new SecureRandom();
 // 隨機數(shù)作為私鑰
 sk = new BigInteger(blq, sr);
 
 // 私鑰的話名字命名
 List<String> toLiSK = KeyPairOperate.transArryToLi(new String[] {"sk=" + sk});
 KeyPairOperate.writePublicKeyToFile(PERFIX_PATH + user + ".properties", toLiSK, false);
 
 BigInteger g = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "g"));
 BigInteger p = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "p"));
 // 公鑰
 pk = g.modPow(sk, p);// g^w mod p -- 注意這兒是正,所以下面驗證的時候是用的負
 List<String> toLiPK = KeyPairOperate.transArryToLi(new String[] {user + "=" + pk});
 KeyPairOperate.writePublicKeyToFile(PUBLIC_KEY_PATH, toLiPK, true);
 System.out.println(user + " 密鑰頒發(fā)完成");
 }
 }
 
 /**
 * @Description: 產(chǎn)生簽名
 * @param sourcefilePath : 待簽名文件路徑
 * @param user:傳入用戶的身份
 * @Date:下午10:41:37
 */
 public static void makeSign(String sourcefilePath, String user) {
 System.out.println(user+ "的文件" + KeyPairOperate.getFileName(sourcefilePath) + " 簽名開始");
 System.out.println("... ...");
 BigInteger q = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "q")); // 素數(shù) q
 BigInteger p = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "p")); // 素數(shù) p
 BigInteger g = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "g")); // q的原根 a
 
 // 私鑰
 BigInteger sk = new BigInteger(KeyPairOperate.getDataFromFile(PERFIX_PATH + user + ".properties", "sk")); // 私鑰
 
 SecureRandom sr = new SecureRandom();
 BigInteger r, x, e, y; 
 r = new BigInteger(q.bitLength(), sr); // 隨機數(shù)
 x = g.modPow(r, p); // g^r mod p
 // e=H(M||x)
 try {
 MessageDigest md5 = MessageDigest.getInstance("MD5");
 md5.update(Files.readAllBytes(Paths.get(sourcefilePath)));
 md5.update(x.toString().getBytes());
 byte[] digest = md5.digest();
 // e 將BigInteger的符號大小表示法轉(zhuǎn)換成一個BigInteger值
 e = new BigInteger(1, digest); 
 // y s2 = r
 y = (r.subtract(sk.multiply(e))).mod(q);
 List<String> transArryToLi = KeyPairOperate.transArryToLi(new String[] {"e="+e,"y="+y});
 String fileName =PERFIX_PATH + user + "_sign_" + KeyPairOperate.getFileName(sourcefilePath) + ".properties";
 KeyPairOperate.writePublicKeyToFile(fileName, transArryToLi, false);
 System.out.println(user+ "的文件" + KeyPairOperate.getFileName(sourcefilePath) + "簽名成功 !");
 } catch (Exception e1) {
 e1.printStackTrace();
 }
 }
 
 /**
 * @Description: 驗證簽名
 * @param sourcePath : 原文件路徑
 * @param user:傳入用戶的身份
 * @Return:void
 * @Date:上午11:07:04
 */
 public static void checkSign(String sourcefilePath, String user) {
 System.out.println("驗證簽名");
 
 BigInteger p = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "p")); // 素數(shù) p
 BigInteger g = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "g")); // q的原根 a
 
 BigInteger pk = new BigInteger(KeyPairOperate.getDataFromFile(PUBLIC_KEY_PATH, user));// 公鑰
 
 String fileName =PERFIX_PATH + user + "_sign_" + KeyPairOperate.getFileName(sourcefilePath) + ".properties"; 
 
 BigInteger e = new BigInteger(KeyPairOperate.getDataFromFile(fileName, "e")); // e 簽名信息1: 產(chǎn)生的簽名信息
 BigInteger y = new BigInteger(KeyPairOperate.getDataFromFile(fileName, "y"));; // y 簽名信息2: 加密后的消息
 
 // 計算的 x'
 BigInteger x1 = g.modPow(y, p); // g^y mod p -- y
 BigInteger x2 = (pk.modPow(e, p)).mod(p); // pk^e mod p 
 BigInteger x = x1.multiply(x2).mod(p); // x1*x2 mod p = (g^y)*(pk^e)mod p
 
 try {
 MessageDigest md5 = MessageDigest.getInstance("MD5");
 md5.update(Files.readAllBytes(Paths.get(sourcefilePath)));
 md5.update(x.toString().getBytes());
 byte[] digest = md5.digest();
 BigInteger h = new BigInteger(1, digest);
 System.out.println("... ...");
 if(e.equals(h))
 System.out.println(user+ "的文件" + KeyPairOperate.getFileName(sourcefilePath) + "驗證通過 !");
 else
 System.out.println(user+ "的文件" + KeyPairOperate.getFileName(sourcefilePath) + "驗證失敗 !");
 } catch (Exception e1) {
 e1.printStackTrace();
 }
 }
}

GetProjectPath:

import java.io.File;

/**
 * @ClassName: GetProjectPath
 * @date: 2020年6月16日 下午10:58:53
 * @Description: 獲取項目絕對路徑
 */
public class GetProjectPath {
 
 public static String getPath() {
 File directory = new File("");
 String courseFile = null;
 try {
 courseFile = directory.getCanonicalPath().replace("\\", "/");
 }catch (Exception e) {
 e.printStackTrace();
 }
 return courseFile;
 }

}

KeyPairOperate

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @ClassName: KeyPairOperate
 * @date: 2020年6月16日 下午9:53:11
 * @Description: 密鑰對的管理與存儲
 */
public class KeyPairOperate {
 
 public static String getFileName(String path) {
 int indexOf = path.lastIndexOf("\\")+1;
 int last = path.lastIndexOf(".");
 return path.substring(indexOf, last);
 }
 
 /**
 * @Description: 工具類,數(shù)組轉(zhuǎn)集合
 * @param para
 * @return
 * @Return:List<String>
 * @Date:上午10:24:33
 */
 public static List<String> transArryToLi(String[] para){
 List<String> li = new ArrayList<String>();
 for(int i=0; i<para.length; i++) {
 li.add(para[i]);
 }
 return li;
 }
 
 /**
 * @Description: 獲取配置文件參數(shù)
 * @param path : 文件路徑
 * @param para : 獲取參數(shù)的key
 * @Date:上午9:46:26
 */
 public static String getDataFromFile(String path, String key) {
 String para = null;
 try {
 Properties pro = new Properties();
 pro.load(new FileInputStream(path));
 para = (String) pro.get(key);
 } catch (Exception e) {
 e.printStackTrace();
 }
 return para;
 }
 
 /**
 * @Description:寫公共密鑰到文件 -- 公鑰證書列表
 * @param path : 存儲的路徑
 * @param param : 參數(shù)
 * @param flag : 是否是追加存儲,公共參數(shù)不是追加,公鑰是追加; 追加: true, 覆蓋: flase
 * @Return:void
 * @Date:上午10:20:25
 */
 public static void writePublicKeyToFile(String path, List<String> param, Boolean flag) {
 try {
 PrintWriter printWriter = new PrintWriter(new FileWriter(path,flag));
 for(String element : param) {
 printWriter.println(element);
 }
 printWriter.close();
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
}

Shtest

import org.junit.Test;
public class Shtest {
 String pathFile ="C:\\Users\\89763\\Desktop\\www.rtf";
 
 @Test
 public void initPara() {
 SchnorrSignature.initPara(12);
 }
 @Test
 public void generateKeyForUser() {
 SchnorrSignature.generateKeyForUser("xiaoming");
 SchnorrSignature.generateKeyForUser("xiaowang");
 }
 @Test
 public void makeSign() {
 SchnorrSignature.makeSign(pathFile,"xiaoming");
 SchnorrSignature.makeSign(pathFile,"xiaowang");
 }
 @Test
 public void checkSign() {
 
 SchnorrSignature.checkSign( pathFile ,"xiaoming");
 SchnorrSignature.checkSign( pathFile ,"xiaowang");
 }

}

以上代碼均來自https://blog.csdn.net/qq_27731689/article/details/106828368  作者:黎明小書生

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JSP request.setAttribute()詳解及實例

    JSP request.setAttribute()詳解及實例

    這篇文章主要介紹了 javascript request.setAttribute()詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 一文帶你了解gson如何序列化子類

    一文帶你了解gson如何序列化子類

    這篇文章主要為大家詳細介紹了gson如何序列化子類的相關(guān)知識,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)和借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • Java底層基于二叉搜索樹實現(xiàn)集合和映射/集合Set功能詳解

    Java底層基于二叉搜索樹實現(xiàn)集合和映射/集合Set功能詳解

    這篇文章主要介紹了Java底層基于二叉搜索樹實現(xiàn)集合和映射/集合Set功能,結(jié)合實例形式分析了Java使用二叉搜索樹實現(xiàn)集合和映射相關(guān)操作技巧,需要的朋友可以參考下
    2020-03-03
  • feignclient?https?接口調(diào)用報證書錯誤的解決方案

    feignclient?https?接口調(diào)用報證書錯誤的解決方案

    這篇文章主要介紹了feignclient?https?接口調(diào)用報證書錯誤的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java中List遍歷刪除元素remove()的方法

    Java中List遍歷刪除元素remove()的方法

    這篇文章主要介紹了Java中List遍歷刪除元素remove()的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 阿里Druid數(shù)據(jù)連接池引發(fā)的線上異常解決

    阿里Druid數(shù)據(jù)連接池引發(fā)的線上異常解決

    這篇文章主要為大家介紹了一次關(guān)于阿里Druid數(shù)據(jù)連接池引發(fā)的線上異常問題的解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • Elasticsearch QueryBuilder簡單查詢實現(xiàn)解析

    Elasticsearch QueryBuilder簡單查詢實現(xiàn)解析

    這篇文章主要介紹了Elasticsearch QueryBuilder簡單查詢實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • Spring?AOP對嵌套方法不起作用的解決

    Spring?AOP對嵌套方法不起作用的解決

    這篇文章主要介紹了Spring?AOP對嵌套方法不起作用的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java循環(huán)對bean的屬性進行賦值的實現(xiàn)

    Java循環(huán)對bean的屬性進行賦值的實現(xiàn)

    本文主要介紹了Java循環(huán)對bean的屬性進行賦值,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • javaweb在線支付功能實現(xiàn)代碼

    javaweb在線支付功能實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了javaweb在線支付功能的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評論