eclipse Schnorr 디지털 서명 실현

Schnorr 디지털 서명,참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
실험 목적
Schnorr 알고리즘 이 디지털 서명 에 사용 되 는 것 을 배우 고 공개 키 서명 에서 가장 기본 적 인 서명 알고리즘-Schnorr 디지털 서명 알고리즘 의 작성 을 파악 합 니 다.
2.실험 요구
1. Schnorr 알고리즘 에 대한 설명 을 잘 알 고 장면 을 사 용 했 습 니 다.
2. Schnorr 디지털 서명 알고리즘 을 잘 알 고 있 습 니 다.
3. 자바 언어 를 어떻게 사용 하 는 지 파악 하여 Schnorr 서명 알고리즘 을 실현 합 니 다.
3.개발 환경
JDK1.8,eclipse。
실험 원리
디지털 서명 이란 메시지 발송 자가 특정한 매개 변 수 를 이용 하여 발생 하 는 메시지 코드 를 말한다.이 메시지 코드 는 메시지 발송 자의 정 체 를 표시 하 는 동시에 보 낸 데이터 의 완전 성 을 표시 할 수 있 기 때문에 보 낸 데이터 가 발송 과정 에서 공격 당 하 는 사람 이 변경 하 는 행 위 를 어느 정도 방지 할 수 있다.한 마디 로 하면 디지털 서명 은 메시지 발송 자가 신분 정보 와 정 보 를 결합 시 켜 만 든 메시지 요약 이다.
디지털 서명 과정 에서 핵심 적 인 두 단 계 는 서명 정 보 를 만 들 고 서명 정 보 를 검증 하 는 것 이다.서명 을 만 드 는 것 은 메시지 발송 자가 특정한 서명 알고리즘 을 사용 하여 데이터 생산 을 메시지 요약 으로 만 드 는 동시에 비밀 키 를 사용 하여 요약 을 암호 화하 고 마지막 으로 암호 화 된 비밀문서 와 원본 데 이 터 를 함께 보 내 는 것 이다.메시지 수신 자가 정 보 를 받 은 후에 먼저 발송 자의 공개 키 로 데이터 의 요약 을 계산 한 다음 에 이 결 과 를 받 은 요약 과 비교 하고 일치 하면 검증 을 통 해 이 소식 이 진실 하고 효과 적 이 라 고 생각 합 니 다.반대로 무효,이 소식 을 버 립 니 다.과정 은 아래 그림 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();
 }
 }
}
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:    ,     
 * @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();
 }
 }
}
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에서 왔 습 니 다.  저자:새벽 서생
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기