日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java判断对称素数_SM2非对称算法的原理及实现 Java SM2的代码案例 | 一生孤注掷温柔 | 小奋斗...

發布時間:2025/3/8 java 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java判断对称素数_SM2非对称算法的原理及实现 Java SM2的代码案例 | 一生孤注掷温柔 | 小奋斗... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SM2橢圓曲線公鑰密碼算法:我國自主知識產權的商用密碼算法,是ECC(Elliptic Curve Cryptosystem)算法的一種,基于橢圓曲線離散對數問題,計算復雜度是指數級,求解難度較大,同等安全程度要求下,橢圓曲線密碼較其他公鑰算法所需密鑰長度小很多。

ECC算法描述:

1、用戶A選定一條適合加密的橢圓曲線Ep(a,b)(如:y2=x3+ax+b),并取橢圓曲線上一點,作為基點G。

2、用戶A選擇一個私有密鑰k,并生成公開密鑰(公鑰PB)K=kG。

3、用戶A將Ep(a,b)和點(公鑰)K,G傳給用戶B。

4、用戶B接到信息后 ,將待傳輸的明文(M)編碼到Ep(a,b)上一點M,并產生一個隨機整數r(r

5、用戶B計算點C1=M+rK;C2=rG。

6、用戶B將C1、C2傳給用戶A。

7、用戶A接到信息后,計算C1-kC2,結果就是點M。因為C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M

再對點M進行解碼就可以得到明文。

密碼學中,描述一條Fp上的橢圓曲線,常用到六個參量:

T=(p,a,b,G,n,h)。

(p 、a 、b 用來確定一條橢圓曲線,G為基點,n為點G的階,h 是橢圓曲線上所有點的個數m與n相除的整數部分)

這幾個參量取值的選擇,直接影響了加密的安全性。參量值一般要求滿足以下幾個條件:

1、p 當然越大越安全,但越大,計算速度會變慢,200位左右可以滿足一般安全要求;

2、p≠n×h;

3、pt≠1 (mod n),1≤t<20;

4、4a3+27b2≠0 (mod p);

5、n 為素數;

6、h≤4。

輕量級密碼術包(BouncyCastle):

一種用于 Java 平臺的開放源碼的輕量級密碼術包;它支持大量的密碼術算法,并提供JCE 1.2.1的實現。

bcprov-ext-jdk15on-160.jar

This release adds support for SHA-3 signatures to CMS, support for the Unified Model of Diffie-Hellman, and a parser for the GNU keybox format. PGP EC operations now support a wider range of curves, the BCJSSE now supports SNI, support has been added for generating ECGOST key transport messages and key wrapping ciphers can now also be used for wrapping general data. Initial low-level support has also been added for EdDSA. In terms of bugs fixed: RSA key pair generation with adjusted certainty values now conforms fully with FIPS PUB 186-4, the CRMF EncryptedValue field now encodes the encrypted value correctly without including the wrapping structure from the encryption, XMSS now validates any private key BDS data before construction, the SM2 signature now fully resets on a sign() call, and PGP secret keys with a null encryptor now calculate the correct checksum. An off by one error in the EST JsseDefaultHostnameAuthorizer valid name matcher has also been fixed. Further details on other additions and bug fixes can be found in the release notes file accompanying the release.

pom.xml

1

2

3

4

5

org.bouncycastle

bcprov-jdk15on

1.60

代碼案例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28package?com.what21.demo.bouncycastle;

import?java.math.BigInteger;

import?org.bouncycastle.math.ec.ECPoint;

public?class?SM2KeyPair?{

/**?公鑰?*/

private??ECPoint?publicKey;

/**?私鑰?*/

private?BigInteger?privateKey;

SM2KeyPair(ECPoint?publicKey,?BigInteger?privateKey)?{

this.publicKey?=?publicKey;

this.privateKey?=?privateKey;

}

public?ECPoint?getPublicKey()?{

return?publicKey;

}

public?BigInteger?getPrivateKey()?{

return?privateKey;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278package?com.what21.demo.bouncycastle;

import?java.math.BigInteger;

import?java.security.SecureRandom;

import?java.util.Arrays;

import?org.bouncycastle.crypto.DerivationFunction;

import?org.bouncycastle.crypto.digests.SHA256Digest;

import?org.bouncycastle.crypto.digests.ShortenedDigest;

import?org.bouncycastle.crypto.generators.KDF1BytesGenerator;

import?org.bouncycastle.crypto.params.ISO18033KDFParameters;

import?org.bouncycastle.math.ec.ECCurve;

import?org.bouncycastle.math.ec.ECPoint;

public?class?SM2Utils?{

/**?素數p?*/

private?static?final?BigInteger?p?=new?BigInteger("FFFFFFFE"?+"FFFFFFFF"

+"FFFFFFFF"?+"FFFFFFFF"?+"FFFFFFFF"?+"00000000"?+"FFFFFFFF"

+"FFFFFFFF",16);

/**?系數a?*/

private?static?final?BigInteger?a?=new?BigInteger("FFFFFFFE"?+"FFFFFFFF"

+"FFFFFFFF"?+"FFFFFFFF"?+"FFFFFFFF"?+"00000000"?+"FFFFFFFF"

+"FFFFFFFC",16);

/**?系數b?*/

private?static?final?BigInteger?b?=new?BigInteger("28E9FA9E"?+"9D9F5E34"

+"4D5A9E4B"?+"CF6509A7"?+"F39789F5"?+"15AB8F92"?+"DDBCBD41"

+"4D940E93",16);

/**?坐標x?*/

private?static?final?BigInteger?xg?=new?BigInteger("32C4AE2C"?+"1F198119"

+"5F990446"?+"6A39C994"?+"8FE30BBF"?+"F2660BE1"?+"715A4589"

+"334C74C7",16);

/**?坐標y?*/

private?static?final?BigInteger?yg?=new?BigInteger("BC3736A2"?+"F4F6779C"

+"59BDCEE3"?+"6B692153"?+"D0A9877C"?+"C62A4740"?+"02DF32E5"

+"2139F0A0",16);

/**?基點G,?G=(xg,yg),其介記為n?*/

private?static?final?BigInteger?n?=new?BigInteger("FFFFFFFE"?+"FFFFFFFF"

+"FFFFFFFF"?+"FFFFFFFF"?+"7203DF6B"?+"21C6052B"?+"53BBF409"

+"39D54123",16);

private?static?SecureRandom?random?=new?SecureRandom();

private?ECCurve.Fp?curve;

private?ECPoint?G;

@SuppressWarnings("deprecation")

public?SM2Utils()?{

curve?=new?ECCurve.Fp(p,//?q

a,//?a

b);//?b

G?=?curve.createPoint(xg,?yg);

}

public?static?String?printHexString(byte[]?b)?{

StringBuilder?builder?=new?StringBuilder();

for?(int?i?=0;?i?

String?hex?=?Integer.toHexString(b[i]?&0xFF);

if?(hex.length()?==1)?{

builder.append('0'+hex);

hex?='0'?+?hex;

}

//System.out.print(hex.toUpperCase());

//System.out.print(hex.toUpperCase());

builder.append(hex);

}

//System.out.println();

return?builder.toString();

}

public?BigInteger?random(BigInteger?max)?{

BigInteger?r?=new?BigInteger(256,?random);

//?int?count?=?1;

while?(r.compareTo(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?

if?(buffer[i]?!=0)

return?false;

}

return?true;

}

/**

*?加密

*?@param?input?待加密消息M

*?@param?publicKey?公鑰

*?@return?byte[]?加密后的字節數組

*/

public?byte[]?encrypt(String?input,?ECPoint?publicKey)?{

//System.out.println("publicKey?is:?"+publicKey);

byte[]?inputBuffer?=?input.getBytes();

//printHexString(inputBuffer);

/*?1?產生隨機數k,k屬于[1,?n-1]?*/

BigInteger?k?=?random(n);

//System.out.print("k:?");

printHexString(k.toByteArray());

/*?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?=?curve.getCofactor();?System.out.print("h:?");

//????????? ?printHexString(h.toByteArray());?if?(publicKey?!=?null)?{?ECPoint

//????????? ?result?=?publicKey.multiply(h);?if?(!result.isInfinity())?{

//????????? ?System.out.println("pass");?}?else?{

//????????? System.err.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?=?kpb.getEncoded(false);

DerivationFunction?kdf?=?new?KDF1BytesGenerator(new?ShortenedDigest(

new?SHA256Digest(),?20));

byte[]?t?=?new?byte[inputBuffer.length];

kdf.init(new?ISO18033KDFParameters(kpbBytes));

kdf.generateBytes(t,?0,?t.length);

if?(allZero(t))?{

//System.err.println("all?zero");

}

/*?6?計算C2=M^t?*/

byte[]?C2?=?new?byte[inputBuffer.length];

for?(int?i?=?0;?i?

C2[i]?=?(byte)?(inputBuffer[i]?^?t[i]);

}

/*?7?計算C3?=?Hash(x2?||?M?||?y2)?*/

byte[]?C3?=?calculateHash(kpb.getXCoord().toBigInteger(),?inputBuffer,

kpb.getYCoord().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?byte[]?decrypt(byte[]?encryptData,?BigInteger?privateKey)?{

//System.out.println("privateKey?is:?"+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?=?dBC1.getEncoded(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));

kdf.generateBytes(t,?0,?t.length);

if?(allZero(t))?{

//System.err.println("all?zero");

}

/*?5?計算M'=C2^t?*/

byte[]?M?=?new?byte[klen];

for?(int?i?=?0;?i?

M[i]?=?(byte)?(encryptData[C1Byte.length?+?i]?^?t[i]);

}

/*?6?計算?u?=?Hash(x2?||?M'?||?y2)?判斷?u?==?C3是否成立?*/

byte[]?C3?=?new?byte[20];

System.arraycopy(encryptData,?encryptData.length?-?20,?C3,?0,?20);

byte[]?u?=?calculateHash(dBC1.getXCoord().toBigInteger(),?M,?dBC1.getYCoord().toBigInteger());

if?(Arrays.equals(u,?C3))?{

//System.out.println("解密成功");

//System.out.println("M'?=?"?+?new?String(M));

return?M;

}?else?{

//System.out.print("u?=?");

//printHexString(u);

//System.out.print("C3?=?");

//printHexString(C3);

//System.err.println("解密驗證失敗");

}

return?null;

}

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?(param.compareTo(min)?>=?0?&&?param.compareTo(max)?

return?true;

}?else?{

return?false;

}

}

/**

*?公鑰校驗

*?@param?publicKey?公鑰

*?@return?boolean?true或false

*/

private?boolean?checkPublicKey(ECPoint?publicKey)?{

if?(!publicKey.isInfinity())?{

BigInteger?x?=?publicKey.getXCoord().toBigInteger();

BigInteger?y?=?publicKey.getYCoord().toBigInteger();

if?(between(x,?new?BigInteger("0"),?p)?&&?between(y,?new?BigInteger("0"),?p))?{

BigInteger?xResult?=?x.pow(3).add(a.multiply(x)).add(b).mod(p);

//System.out.println("xResult:?"?+?xResult.toString());

BigInteger?yResult?=?y.pow(2).mod(p);

//System.out.println("yResult:?"?+?yResult.toString());

if?(yResult.equals(xResult)?&&?publicKey.multiply(n).isInfinity())?{

return?true;

}

}

return?false;

}?else?{

return?false;

}

}

/**

*?獲得公私鑰對

*?@return

*/

public?SM2KeyPair?generateKeyPair()?{

BigInteger?d?=?random(n.subtract(new?BigInteger("1")));

SM2KeyPair?keyPair?=new?SM2KeyPair(G.multiply(d).normalize(),?d);

if?(checkPublicKey(keyPair.getPublicKey()))?{

//System.out.println("generate?key?successfully");

return?keyPair;

}else?{

//System.err.println("generate?key?failed");

return?null;

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21package?com.what21.demo.bouncycastle;

import?java.util.Arrays;

public?class?App?{

/**

*?@param?args

*/

public?static?void?main(String[]?args)?{

SM2Utils?sm2?=new?SM2Utils();

SM2KeyPair?keyPair?=?sm2.generateKeyPair();

String?text?="小奮斗{www.what21.com}";

System.out.println("文本為:"?+?text);

byte[]?data?=?sm2.encrypt(text,keyPair.getPublicKey());

System.out.println("加密為:"+Arrays.toString(data));

byte[]?data2?=?sm2.decrypt(data,?keyPair.getPrivateKey());

System.out.println("解密為:"?+new?String(data2));

}

}

程序輸入:

1

2

3文本為:小奮斗{www.what21.com}

加密為:[4,?66,?87,?4,?-112,?-103,?73,?-79,?-26,?-2,?50,?110,?-45,?119,?-63,?-94,?70,?-24,?111,?93,?79,?47,?2,?92,?-118,?-65,?-87,?-20,?12,?43,?-121,?20,?-39,?-35,?-27,?4,?20,?103,?26,?89,?48,?-95,?-64,?-6,?93,?-35,?69,?63,?-64,?-119,?-14,?65,?11,?24,?43,?-119,?50,?89,?60,?15,?61,?83,?33,?-90,?5,?-44,?-107,?-118,?98,?0,?-12,?10,?0,?-73,?41,?-91,?69,?106,?100,?109,?117,?99,?31,?97,?127,?-120,?64,?-76,?52,?98,?-52,?-79,?96,?19,?-71,?-100,?-111,?-93,?113,?45,?92,?105,?46,?124,?-19,?-66,?-102,?106,?2,?75]

解密為:小奮斗{www.what21.com}

總結

以上是生活随笔為你收集整理的java判断对称素数_SM2非对称算法的原理及实现 Java SM2的代码案例 | 一生孤注掷温柔 | 小奋斗...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。