eclipseはSchnorrデジタル署名を実現します。


Schnorrデジタル署名は、皆様の参考になります。具体的な内容は以下の通りです。
一、実験の目的
Schnorrアルゴリズムのデジタル署名における使用を学び、公開鍵署名における最も基本的な署名アルゴリズム・Schnorrデジタル署名アルゴリズムの作成を把握する。
二、実験要求
1. Schnorrアルゴリズムの説明をよく知っています。もうその使用シーンです。
2. Schnorrデジタル署名アルゴリズムに詳しい。
3. Java言語の使い方をマスターして、Schnorr署名アルゴリズムを実現します。
三、開発環境
JDK 1.8、eclipse。
四、実験原理
デジタル署名とは、メッセージ送信者が特定のパラメータを利用して生成したメッセージコードであり、メッセージ送信者の真のアイデンティティを識別するために使用され、送信されたデータの完全性を識別することができるので、送信中に攻撃者によって改ざんされる行為はある程度防止される。簡単に言えば、デジタル署名とは、メッセージ送信者がアイデンティティ情報とメッセージを組み合わせて生成するメッセージの要約である。
デジタル署名プロセスにおけるコアの2つのステップは、署名情報と署名情報の検証を生成することであり、署名を生成することは、メッセージ送信者が特定の署名アルゴリズムを用いてデータを抽出し、秘密鍵を用いてその要約を暗号化し、最後に暗号化された暗号文と元のデータを一緒に送信することである。メッセージ受信者は、情報を受信した後、まず送信者の公開鍵でデータの要約を計算し、その後、この結果を受信した要約と比較し、一致すれば、このメッセージが実際に有効であると検証することができる。このメッセージは、逆に無効です。プロセスは下図1に示します。

a)デジタル署名暗号化プロセス
b)デジタル署名復号検証プロセス

図1デジタル署名プロセス
Schnorr署名アルゴリズムはドイツの数学者、暗号学者Claus Schnorrによって提案され、Elgamal署名案の変種である。
具体的な手順は以下の通りです。
まず公開鍵/秘密鍵ペアを生成します。プロセスは以下の通りです。
a. 素数和を選択します。素数です。
b. 整数を選択します。グローバル公開鍵パラメータを構成し、ユーザグループ内の各ユーザが使用できます。
c. ランダム整数をユーザの秘密鍵として選択します。
d. 公開鍵を計算します
鍵ペアのユーザには、以下のプロセスによって署名が生成される。
a. ランダム整数を選択し、計算します。
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/";
 //       
 private static final String PARAM_PATH = PERFIX_PATH + "initParams.properties";
 //        
 private static final String PUBLIC_KEY_PATH = PERFIX_PATH + "publicKey.properties";
 
 /**
 * @Description:        ,                  
 * @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("         ,           ,            ,             ,             ");
 }else {
 System.out.println("      ,      ... ...");
 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    ,    (     1 - 1/2certainty)       bitLength    
 q = new BigInteger(blq, certainty, sr);
 qp = BigInteger.ONE;
 do { //        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;
 }
 //       
 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 + "       ,             ,     ");
 }else {
 System.out.println("     ,   ");
 System.out.println("... ...");
 BigInteger sk,pk;//      
 int blq = Integer.parseInt(KeyPairOperate.getDataFromFile(PARAM_PATH, "blq"));
 SecureRandom sr = new SecureRandom();
 //        
 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 + "       ");
 }
 }
 
 /**
 * @Description:     
 * @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")); //    q
 BigInteger p = new BigInteger(KeyPairOperate.getDataFromFile(PARAM_PATH, "p")); //    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); //    
 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             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")); //    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:        
 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();
 }
 }
}
Get Project Path:

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:    ,     
 * @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:         
 * @param path :     
 * @param para :      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 :   
 * @param flag :        ,        ,     ;   : 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();
 }
 }
}
シートスト

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/articale/detail/10828368から来ています。  作者:夜明けの小书生
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。