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}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

multipartfile 获取音频时长_抖音音频下载捷径:一键提取音频,安卓+ios全通用,完全免费...

本文相关&#xff1a;抖音音频提取、抖音音频快捷指令、捷径怎么获取抖音音乐…昨天有抖友分享了一个抖音短视频链接&#xff0c;告诉我&#xff0c;她很喜欢这个视频里的歌曲&#xff0c;但是在很多歌曲app上面却找不到相同的版本&#xff0c;然后就问我&#xff0c;有没有什么…

python可以做特效吗_学习mel语言,Python,JavaScript到什么程度才能做一下大型特效,要自已开发插件脚本呢?...

感谢邀请。首先自己要在某一方面要擅长&#xff0c;认准一个定位。比如android是钥匙做前端应用软件的&#xff0c;python可以做爬虫及其人工智能&#xff0c;js做全段网页&#xff0c;java主要是做后端的1、我们程序员对于开发软件来说&#xff0c;无论你选择的是那种语言&…

POJ2513-Colored Sticks

/*思路&#xff1a;类似图论中“一笔画”问题&#xff0c;两根木棒的相连接的端点是一样的颜色&#xff0c;&#xff08;a,b&#xff09;--(b,c)--(c, d)....方法&#xff1a;trie树并查集&#xff0c; 利用trie树建立字符串和某一个节点的映射&#xff0c;并将这些和字符串构成…

php windows共享内存,给PHP开启shmop扩展实现共享内存

这篇文章主要介绍了关于给PHP开启shmop扩展实现共享内存&#xff0c;有着一定的参考价值&#xff0c;现在分享给大家&#xff0c;有需要的朋友可以参考一下在项目开发中&#xff0c;想要实现PHP多个进程之间共享数据的功能&#xff0c;让客户端连接能够共享一个状态&#xff0c…

导入ansys的实体怎么进行parameter_ANSYS在线缆线束设计中的仿真应用

ANSYS采用ANSYS Maxwell、Q3D、Twin Builder等电磁仿真软件&#xff0c;从线缆线束设计、寄生参数RLCG提取、到系统电磁兼容提供了全面仿真分析。创建模型ANSYS在Maxwell软件基础上提出针对用户定制化的“线缆线束设计工具包”&#xff0c;帮助客户参数化建立特定几何模型&…

怎么做95置信区间图_这种动态的OD图怎么做?简单3步快速搞定

之前在视频号中发过一个单车的出行数据可视化效果。动态展示了某天单车不同时段的运行情况&#xff0c;这种动态的OD可视化效果是如何制作的呢&#xff1f;使用的是kepler.gl进行制作的&#xff0c;其实非常简单&#xff0c;3步即可快速搞定。一、数据软件准备1、软件制作这种动…

php抖音跳转地址,PHP如何实现解析抖音无水印视频

问题来源很多时候你在douyin里看到了一个短视频&#xff0c;想复制下来自己编辑文字来发布&#xff0c;可是视频里的水印却是原者的。这个时候你想把水印去掉&#xff0c;你要如何做呢&#xff1f;这里提供PHP实现去除水印的主要方法&#xff0c;其实很简单。使用方法&#xff…

php 分割二维数组,拆分二维数组 php

把以下数组拆分&#xff1a;{"errcode": 0,"msg": "成功","data": {"list": [{"ticket_no": "1","options": ["周四301","周四302","周四303"],"play_ty…

Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解

1 /*2 Dijkstra算法用优先队列来实现&#xff0c;实现了每一条边最多遍历一次。 要知道&#xff0c;我们从队列头部找到的都是到3 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其他点&#xff08;被更新的节点可以在队列中4 &#xff0c;也可以是…

php times33,PHP Hash算法:Times33算法代码实例

最近看书&#xff0c;里面提到了一些Hash算法。比较有印象的是Times33&#xff0c;当时理解不是很透测&#xff0c;今天写了段程序来验证了一下。先上代码&#xff1a;复制代码 代码如下:/*** CRC32 Hash function* param $str* return int*/function hash32($str){return crc3…

捡到vivo手机怎么清除账号_为什么现在买手机,很少会去考虑OPPO和vivo呢?看一下老板怎么说...

不知道大家是否注意到&#xff0c;近年来OPPO和vivo的报道越来越少&#xff0c;而华为、荣耀和小米出现的频率越来越高。此外&#xff0c;网络上还有另外一个声音&#xff0c;一个专业的机友朋友说&#xff0c;宁可选择小米、OPPO和vivo&#xff0c;为什么熟悉自己手机的人不考…

php分析图片中水印的位置,关于ThinkPHP打水印及设置水印位置的分析

这篇文章主要介绍了ThinkPHP打水印及设置水印位置的方法,结合实例形式分析了thinkPHP打印与设置水印的相关操作步骤与具体实现技巧,需要的朋友可以参考下本文实例讲述了ThinkPHP打水印及设置水印位置的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;最近在用Thin…

华为交换机命令_华为交换机常用命令

华为交换机常用命令&#xff1a;1、display current-configuration 显示当前配置2、display interface GigabitEthernet 1/1/4 显示接口信息3、display packet-filter interface GigabitEthernet 1/1/4 显示接口acl应用信息4、display acl all 显示所有acl设置 3900系列交换机5…

java中两种添加监听器的策略

/*第一种&#xff1a;将事件的处理委托给其他对象&#xff0c;下面的例子是委托给了MyListener&#xff08;implements ActionListener&#xff09;*/ 1 import java.applet.Applet;2 import java.awt.event.*;3 import java.awt.*;4 public class ChangeColor extends Applet{…

php dos命令用不了,windows下如何使用DOS命令强制复制文件

有的时候&#xff0c;我们可能需要替换某些目录下的一些文件&#xff0c;手动去一个个目录找的话&#xff0c;就会比较麻烦&#xff0c;这时候&#xff0c;就是我们程序员上场的时候了&#xff0c;程序虽然好写&#xff0c;但是dos命令并不是每个人都玩的转的&#xff0c;而且最…

java的栈图形演示

1 import java.awt.*;2 import javax.swing.*;3 import java.awt.event.*;4 /*5 指示发生了组件定义的动作的语义事件。当特定于组件的动作&#xff08;比如被按下&#xff09;发生时&#xff0c;由组件&#xff08;比如 Button&#xff09;生成此高级别事件。6 事件被传递给每…

python播放本地视频_python opencv 读取本地视频文件 修改ffmpeg的方法

Python opencv 读取视频的三种情况&#xff1a;情况一&#xff1a;通过摄像头采集视频情况二&#xff1a;通过本地视频文件获取视频情况三&#xff1a;通过摄像头录制视频&#xff0c;再读取录制的视频摄像头采集、本地视频文件的读取、写视频文件&#xff0c;网上都有代码。我…

kali里PHP文件502错误,解决Linux Kali iptables开放22端口失败等一系列问题

这篇文章是针对2020年下载安装的kali系统碰到的关于 iptables开放22端口失败等一系列问题的解决办法&#xff0c;如果是其它系统&#xff0c;可以借鉴一下思路。各种报错&#xff1a;# sudo systemctl start iptablesFailed to start iptables.service: Unit iptables.service …

中缀试转后缀试及前缀试并计算其结果

1 /*2 参考大神nb的代码&#xff0c;感觉思路不错&#xff01;终于搞明白了&#xff01;一开始不明白在计算表达式的时候&#xff0c;利用栈到底做了什么&#xff01;现在感觉我们利用栈就是模拟我们书面上计算表达式&#xff0c;3 将优先级高的运算先计算出来&…

ros如何编译python文件_Python为ROS编写一个简单的发布者和订阅者

Python为ROS编写一个简单的发布者和订阅者1.创建工作空间1.1建立文件夹hello_rospy,再在该目录下建立子目录src,并创建工作空间mkdir -p ~/hello_rospy/srccd ~/hello_rospy/srccatkin_init_workspace1.2 编译cd ~/hello_rospy/catkin_make1.3设置运行环境echo "source ~/…