-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
重新调式SM2加密和解密算法,增加了Hex.encode() 和Hex.decode()
- Loading branch information
Showing
19 changed files
with
1,563 additions
and
1,619 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 14 | ||
VisualStudioVersion = 14.0.25420.1 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SM2Crypto", "SM2Crypto\SM2Crypto.csproj", "{DFC19643-ABE0-49F7-A087-31314B742408}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{DFC19643-ABE0-49F7-A087-31314B742408}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{DFC19643-ABE0-49F7-A087-31314B742408}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{DFC19643-ABE0-49F7-A087-31314B742408}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{DFC19643-ABE0-49F7-A087-31314B742408}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<configuration> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> | ||
</startup> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using System; | ||
using System.Globalization; | ||
using System.Text; | ||
|
||
namespace SM2Crypto.Lib | ||
{ | ||
/// <summary> | ||
/// 字节数组操作扩展类 | ||
/// </summary> | ||
static class ByteUtils | ||
{ | ||
internal static byte[] AsciiBytes(string s) | ||
{ | ||
byte[] bytes = new byte[s.Length]; | ||
|
||
for (int i = 0; i < s.Length; i++) | ||
{ | ||
bytes[i] = (byte)s[i]; | ||
} | ||
|
||
return bytes; | ||
} | ||
|
||
internal static byte[] HexToByteArray(this string hexString) | ||
{ | ||
byte[] bytes = new byte[hexString.Length / 2]; | ||
|
||
for (int i = 0; i < hexString.Length; i += 2) | ||
{ | ||
string s = hexString.Substring(i, 2); | ||
bytes[i / 2] = byte.Parse(s, NumberStyles.HexNumber, null); | ||
} | ||
|
||
return bytes; | ||
} | ||
|
||
internal static string ByteArrayToHex(this byte[] bytes) | ||
{ | ||
StringBuilder builder = new StringBuilder(bytes.Length * 2); | ||
|
||
foreach (byte b in bytes) | ||
{ | ||
builder.Append(b.ToString("X2")); | ||
} | ||
|
||
return builder.ToString(); | ||
} | ||
|
||
internal static string ByteArrayToHex(this byte[] bytes, int len) | ||
{ | ||
return ByteArrayToHex(bytes).Substring(0, len * 2); | ||
} | ||
|
||
internal static byte[] RepeatByte(byte b, int count) | ||
{ | ||
byte[] value = new byte[count]; | ||
|
||
for (int i = 0; i < count; i++) | ||
{ | ||
value[i] = b; | ||
} | ||
|
||
return value; | ||
} | ||
|
||
internal static byte[] SubBytes(this byte[] bytes, int startIndex, int length ) | ||
{ | ||
byte[] res = new byte[length]; | ||
Array.Copy(bytes, startIndex, res, 0, length); | ||
return res; | ||
} | ||
|
||
internal static byte[] XOR(this byte[] value) | ||
{ | ||
byte[] res = new byte[value.Length]; | ||
for (int i = 0; i < value.Length; i++) | ||
{ | ||
res[i] ^= value[i]; | ||
} | ||
return res; | ||
} | ||
|
||
internal static byte[] XOR(this byte[] valueA, byte[] valueB) | ||
{ | ||
int len = valueA.Length; | ||
byte[] res = new byte[len]; | ||
for (int i = 0; i < len; i++) | ||
{ | ||
res[i] = (byte)(valueA[i] ^ valueB[i]); | ||
} | ||
return res; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Org.BouncyCastle.Math.EC; | ||
using Org.BouncyCastle.Crypto; | ||
using Org.BouncyCastle.Crypto.Parameters; | ||
using Org.BouncyCastle.Math; | ||
|
||
namespace SM2Crypto.Lib | ||
{ | ||
public class Cipher | ||
{ | ||
private int ct; | ||
private ECPoint p2; | ||
private SM3Digest sm3keybase; | ||
private SM3Digest sm3c3; | ||
private byte[] key; | ||
private byte keyOff; | ||
|
||
public Cipher() | ||
{ | ||
this.ct = 1; | ||
this.key = new byte[32]; | ||
this.keyOff = 0; | ||
} | ||
|
||
public static byte[] byteConvert32Bytes(BigInteger n) | ||
{ | ||
byte[] tmpd = null; | ||
if (n == null) | ||
{ | ||
return null; | ||
} | ||
|
||
if (n.ToByteArray().Length == 33) | ||
{ | ||
tmpd = new byte[32]; | ||
Array.Copy(n.ToByteArray(), 1, tmpd, 0, 32); | ||
} | ||
else if (n.ToByteArray().Length == 32) | ||
{ | ||
tmpd = n.ToByteArray(); | ||
} | ||
else | ||
{ | ||
tmpd = new byte[32]; | ||
for (int i = 0; i < 32 - n.ToByteArray().Length; i++) | ||
{ | ||
tmpd[i] = 0; | ||
} | ||
Array.Copy(n.ToByteArray(), 0, tmpd, 32 - n.ToByteArray().Length, n.ToByteArray().Length); | ||
} | ||
return tmpd; | ||
} | ||
|
||
private void Reset() | ||
{ | ||
this.sm3keybase = new SM3Digest(); | ||
this.sm3c3 = new SM3Digest(); | ||
|
||
byte[] p = byteConvert32Bytes(p2.Normalize().XCoord.ToBigInteger()); | ||
this.sm3keybase.BlockUpdate(p, 0, p.Length); | ||
this.sm3c3.BlockUpdate(p, 0, p.Length); | ||
|
||
p = byteConvert32Bytes(p2.Normalize().YCoord.ToBigInteger()); | ||
this.sm3keybase.BlockUpdate(p, 0, p.Length); | ||
this.ct = 1; | ||
NextKey(); | ||
} | ||
|
||
private void NextKey() | ||
{ | ||
SM3Digest sm3keycur = new SM3Digest(this.sm3keybase); | ||
sm3keycur.Update((byte)(ct >> 24 & 0xff)); | ||
sm3keycur.Update((byte)(ct >> 16 & 0xff)); | ||
sm3keycur.Update((byte)(ct >> 8 & 0xff)); | ||
sm3keycur.Update((byte)(ct & 0xff)); | ||
sm3keycur.DoFinal(key, 0); | ||
this.keyOff = 0; | ||
this.ct++; | ||
} | ||
|
||
public ECPoint Init_enc(SM2 sm2, ECPoint userKey) | ||
{ | ||
AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.GenerateKeyPair(); | ||
ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private; | ||
ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public; | ||
BigInteger k = ecpriv.D; | ||
ECPoint c1 = ecpub.Q; | ||
this.p2 = userKey.Multiply(k); | ||
Reset(); | ||
return c1; | ||
} | ||
|
||
public void Encrypt(byte[] data) | ||
{ | ||
this.sm3c3.BlockUpdate(data, 0, data.Length); | ||
for (int i = 0; i < data.Length; i++) | ||
{ | ||
if (keyOff == key.Length) | ||
{ | ||
NextKey(); | ||
} | ||
data[i] ^= key[keyOff++]; | ||
} | ||
} | ||
|
||
public void Init_dec(BigInteger userD, ECPoint c1) | ||
{ | ||
this.p2 = c1.Multiply(userD); | ||
Reset(); | ||
} | ||
|
||
public void Decrypt(byte[] data) | ||
{ | ||
for (int i = 0; i < data.Length; i++) | ||
{ | ||
if (keyOff == key.Length) | ||
{ | ||
NextKey(); | ||
} | ||
data[i] ^= key[keyOff++]; | ||
} | ||
|
||
this.sm3c3.BlockUpdate(data, 0, data.Length); | ||
} | ||
|
||
public void Dofinal(byte[] c3) | ||
{ | ||
byte[] p = byteConvert32Bytes(p2.Normalize().YCoord.ToBigInteger()); | ||
this.sm3c3.BlockUpdate(p, 0, p.Length); | ||
this.sm3c3.DoFinal(c3, 0); | ||
Reset(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
using Org.BouncyCastle.Crypto.Generators; | ||
using Org.BouncyCastle.Math.EC; | ||
using Org.BouncyCastle.Math; | ||
using Org.BouncyCastle.Crypto; | ||
using Org.BouncyCastle.Crypto.Parameters; | ||
using Org.BouncyCastle.Security; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Org.BouncyCastle.Crypto.Digests; | ||
|
||
namespace SM2Crypto.Lib | ||
{ | ||
public class SM2 | ||
{ | ||
public static SM2 Instance | ||
{ | ||
get | ||
{ | ||
return new SM2(); | ||
} | ||
|
||
} | ||
public static SM2 InstanceTest | ||
{ | ||
get | ||
{ | ||
return new SM2(); | ||
} | ||
|
||
} | ||
|
||
public static readonly string[] sm2_param = { | ||
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",// p,0 | ||
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",// a,1 | ||
"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",// b,2 | ||
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",// n,3 | ||
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",// gx,4 | ||
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" // gy,5 | ||
}; | ||
|
||
public string[] ecc_param = sm2_param; | ||
|
||
public readonly BigInteger ecc_p; | ||
public readonly BigInteger ecc_a; | ||
public readonly BigInteger ecc_b; | ||
public readonly BigInteger ecc_n; | ||
public readonly BigInteger ecc_gx; | ||
public readonly BigInteger ecc_gy; | ||
|
||
public readonly ECCurve ecc_curve; | ||
public readonly ECPoint ecc_point_g; | ||
|
||
public readonly ECDomainParameters ecc_bc_spec; | ||
|
||
public readonly ECKeyPairGenerator ecc_key_pair_generator; | ||
|
||
private SM2() | ||
{ | ||
ecc_param = sm2_param; | ||
|
||
ECFieldElement ecc_gx_fieldelement; | ||
ECFieldElement ecc_gy_fieldelement; | ||
|
||
ecc_p = new BigInteger(ecc_param[0], 16); | ||
ecc_a = new BigInteger(ecc_param[1], 16); | ||
ecc_b = new BigInteger(ecc_param[2], 16); | ||
ecc_n = new BigInteger(ecc_param[3], 16); | ||
ecc_gx = new BigInteger(ecc_param[4], 16); | ||
ecc_gy = new BigInteger(ecc_param[5], 16); | ||
|
||
|
||
ecc_gx_fieldelement = new FpFieldElement(ecc_p, ecc_gx); | ||
ecc_gy_fieldelement = new FpFieldElement(ecc_p, ecc_gy); | ||
|
||
ecc_curve = new FpCurve(ecc_p, ecc_a, ecc_b); | ||
ecc_point_g = new FpPoint(ecc_curve, ecc_gx_fieldelement, ecc_gy_fieldelement); | ||
|
||
ecc_bc_spec = new ECDomainParameters(ecc_curve, ecc_point_g, ecc_n); | ||
|
||
ECKeyGenerationParameters ecc_ecgenparam; | ||
ecc_ecgenparam = new ECKeyGenerationParameters(ecc_bc_spec, new SecureRandom()); | ||
|
||
ecc_key_pair_generator = new ECKeyPairGenerator(); | ||
ecc_key_pair_generator.Init(ecc_ecgenparam); | ||
} | ||
|
||
public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey) | ||
{ | ||
SM3Digest sm3 = new SM3Digest(); | ||
byte[] p; | ||
// userId length | ||
int len = userId.Length * 8; | ||
sm3.Update((byte)(len >> 8 & 0x00ff)); | ||
sm3.Update((byte)(len & 0x00ff)); | ||
|
||
// userId | ||
sm3.BlockUpdate(userId, 0, userId.Length); | ||
|
||
// a,b | ||
p = ecc_a.ToByteArray(); | ||
sm3.BlockUpdate(p, 0, p.Length); | ||
p = ecc_b.ToByteArray(); | ||
sm3.BlockUpdate(p, 0, p.Length); | ||
// gx,gy | ||
p = ecc_gx.ToByteArray(); | ||
sm3.BlockUpdate(p, 0, p.Length); | ||
p = ecc_gy.ToByteArray(); | ||
sm3.BlockUpdate(p, 0, p.Length); | ||
|
||
// x,y | ||
p = userKey.AffineXCoord.ToBigInteger().ToByteArray(); | ||
sm3.BlockUpdate(p, 0, p.Length); | ||
p = userKey.AffineYCoord.ToBigInteger().ToByteArray(); | ||
sm3.BlockUpdate(p, 0, p.Length); | ||
|
||
// Z | ||
byte[] md = new byte[sm3.GetDigestSize()]; | ||
sm3.DoFinal(md, 0); | ||
|
||
return md; | ||
} | ||
} | ||
} |
Oops, something went wrong.