SM2公钥加密Java代码⽰例最近研究了⼀下国密算法SM2中的公钥加密部分,⽤Java写了⼀个简单的例⼦。
/*⽂件:SM2.java*/
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Arrays;
import org.ECCurve;
import org.ECPoint;
import pto.DerivationFunction;
import pto.digests.ShortenedDigest;
import pto.digests.SHA256Digest;
import ators.KDF1BytesGenerator;
import pto.params.ISO18033KDFParameters;
public class SM02 {
private static BigInteger n = new BigInteger("FFFFFFFE" + "FFFFFFFF"
+ "FFFFFFFF" + "FFFFFFFF" + "7203DF6B" + "21C6052B" + "53BBF409"
+ "39D54123", 16);
private static BigInteger p = new BigInteger("FFFFFFFE" + "FFFFFFFF"
+ "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF"
+ "FFFFFFFF", 16);
private static BigInteger a = new BigInteger("FFFFFFFE" + "FFFFFFFF"
+ "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF"
+ "FFFFFFFC", 16);
private static BigInteger b = new BigInteger("28E9FA9E" + "9D9F5E34"
+ "4D5A9E4B" + "CF6509A7" + "F39789F5" + "15AB8F92" + "DDBCBD41"
+ "4D940E93", 16);
private static BigInteger gx = new BigInteger("32C4AE2C" + "1F198119"
+ "5F990446" + "6A39C994" + "8FE30BBF" + "F2660BE1" + "715A4589"
+ "334C74C7", 16);
private static BigInteger gy = new BigInteger("BC3736A2" + "F4F6779C"
+ "59BDCEE3" + "6B692153" + "D0A9877C" + "C62A4740" + "02DF32E5"
+ "2139F0A0", 16);
private static SecureRandom random = new SecureRandom();
private ECCurve.Fp curve;
private ECPoint G;
public static void printHexString(byte[] b) {
for (int i = 0; i < b.length; i++) {
String hex = HexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
System.out.UpperCase());
}
System.out.println();
}
public BigInteger random(BigInteger max) {
BigInteger r = new BigInteger(256, random);
// int count = 1;
while (rpareTo(max) >= 0) {
r = new BigInteger(128, random);
// count++;
}
// System.out.println("count: " + count);
return r;
}
private boolean allZero(byte[] buffer) {
for (int i = 0; i < buffer.length; i++) {
if (buffer[i] != 0)
return false;
}
return true;
}
public byte[] encrypt(String input, ECPoint publicKey) {
byte[] inputBuffer = Bytes();
printHexString(inputBuffer);
java源代码加密/* 1 产⽣随机数k,k属于[1, n-1] */
BigInteger k = random(n);
System.out.print("k: ");
ByteArray());
/* 2 计算椭圆曲线点C1 = [k]G = (x1, y1) */
ECPoint C1 = G.multiply(k);
byte[] C1Buffer = C1.getEncoded(false);
System.out.print("C1: ");
printHexString(C1Buffer);
/*
* 3 计算椭圆曲线点 S = [h]Pb * curve没有指定余因⼦,h为空
*
* BigInteger h = Cofactor(); System.out.print("h: ");
* ByteArray()); if (publicKey != null) { ECPoint
* result = publicKey.multiply(h); if (!result.isInfinity()) {
* System.out.println("pass"); } else {
* println("计算椭圆曲线点 S = [h]Pb失败"); return null; } }
*/
/* 4 计算 [k]PB = (x2, y2) */
ECPoint kpb = publicKey.multiply(k).normalize();
/* 5 计算 t = KDF(x2||y2, klen) */
byte[] kpbBytes = Encoded(false);
DerivationFunction kdf = new KDF1BytesGenerator(new ShortenedDigest( new SHA256Digest(), 20));
byte[] t = new byte[inputBuffer.length];
kdf.init(new ISO18033KDFParameters(kpbBytes));
if (allZero(t)) {
}
/* 6 计算C2=M^t */
byte[] C2 = new byte[inputBuffer.length];
for (int i = 0; i < inputBuffer.length; i++) {
C2[i] = (byte) (inputBuffer[i] ^ t[i]);
}
/* 7 计算C3 = Hash(x2 || M || y2) */
byte[] C3 = XCoord().toBigInteger(), inputBuffer, YCoord().toBigInteger());
/* 8 输出密⽂ C=C1 || C2 || C3 */
byte[] encryptResult = new byte[C1Buffer.length + C2.length + C3.length];
System.arraycopy(C1Buffer, 0, encryptResult, 0, C1Buffer.length); System.arraycopy(C2, 0, encryptResult, C1Buffer.length, C2.length);
System.arraycopy(C3, 0, encryptResult, C1Buffer.length + C2.length,
C3.length);
System.out.print("密⽂: ");
printHexString(encryptResult);
return encryptResult;
}
public void decrypt(byte[] encryptData, BigInteger privateKey) {
System.out.println("encryptData length: " + encryptData.length);
byte[] C1Byte = new byte[65];
System.arraycopy(encryptData, 0, C1Byte, 0, C1Byte.length);
ECPoint C1 = curve.decodePoint(C1Byte).normalize();
/* 计算[dB]C1 = (x2, y2) */
ECPoint dBC1 = C1.multiply(privateKey).normalize();
/* 计算t = KDF(x2 || y2, klen) */
byte[] dBC1Bytes = Encoded(false);
DerivationFunction kdf = new KDF1BytesGenerator(new ShortenedDigest( new SHA256Digest(), 20));
int klen = encryptData.length - 65 - 20;
System.out.println("klen = " + klen);
byte[] t = new byte[klen];
kdf.init(new ISO18033KDFParameters(dBC1Bytes));
if (allZero(t)) {
}
/* 5 计算M'=C2^t */
byte[] M = new byte[klen];
for (int i = 0; i < M.length; i++) {
M[i] = (byte) (encryptData[C1Byte.length + i] ^ t[i]);
}
printHexString(M);
/* 6 计算 u = Hash(x2 || M' || y2) 判断 u == C3是否成⽴ */
byte[] C3 = new byte[20];
System.out.println("M = " + new String(M));
System.arraycopy(encryptData, encryptData.length - 20, C3, 0, 20);
byte[] u = XCoord().toBigInteger(), M, dBC1
.getYCoord().toBigInteger());
if (Arrays.equals(u, C3)) {
System.out.println("解密成功");
} else {
System.out.print("u = ");
printHexString(u);
System.out.print("C3 = ");
printHexString(C3);
}
}
private byte[] calculateHash(BigInteger x2, byte[] M, BigInteger y2) { ShortenedDigest digest = new ShortenedDigest(new SHA256Digest(), 20); byte[] buf = x2.toByteArray();
digest.update(buf, 0, buf.length);
digest.update(M, 0, M.length);
buf = y2.toByteArray();
digest.update(buf, 0, buf.length);
buf = new byte[20];
digest.doFinal(buf, 0);
return buf;
}
private boolean between(BigInteger param, BigInteger min, BigInteger max) { if (parampareTo(min) >= 0 && parampareTo(max) < 0) {
return true;
} else {
return false;
}
}
private boolean checkPublicKey(ECPoint publicKey) {
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论