eclipse 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에서 왔 습 니 다. 저자:새벽 서생이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
m1 이클립스에 oracle cloud (오라클 클라우드)연결하기m1에는 oracle이 설치되지 않는다.... 큰맘먹고 지른 m1인데 oracle이 설치되지 않는다니... 하지만 이뻐서 용서가 된다. 이거 때문에 웹 개발 국비수업을 듣는 도중에 몇번 좌절하고 스트레스를 크게 받았...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.