当前位置: 首页 > news >正文

signature=735f4378ec01919f23285d0d2557be19,OPENSSL编程 第二十章 椭圆曲线

20.1  ECC介绍

椭圆曲线算法可以看作是定义在特殊集合下数的运算,满足一定的规则。椭圆曲线在如下两个域中定义:Fp域和F2m域。

Fp域,素数域,p为素数;

F2m域:特征为2的有限域,称之为二元域或者二进制扩展域。该域中,元素的个数为2m个。

椭圆曲线标准文档如下:

1)    X9.62

Public Key Cryptography For The Financial Services Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA);

2)    SEC 1

SEC 1:Elliptic Curve Cryptography;

3)    SEC 2

SEC 2: Recommended Elliptic Curve Domain Parameters;

4)    NIST

(U.S.) National Institute of Standards and Technology,美国国家标准。

这些标准一般都描述了Fp域和F2m域、椭圆曲线参数、数据转换、密钥生成以及推荐了多种椭圆曲线。

一些术语说明:

1)    椭圆曲线的阶(order of a curve)

椭圆曲线所有点的个数,包含无穷远点;

2)    椭圆曲线上点的阶(order of a point)

P为椭圆曲线上的点,nP=无穷远点,n取最小整数,既是P的阶;

3)    基点(base point)

椭圆曲线参数之一,用G表示,是椭圆曲线上都一个点;

4)    余因子(cofactor)

椭圆曲线的余因子,用h表示,为椭圆曲线点的个数/基点的阶

5)    椭圆曲线参数:

素数域:

(p,a,b,G,n,h)

其中,p为素数,确定Fp,a和b确定椭圆曲线方程,G为基点,n为G的阶,h为余因子。

二进制扩展域:

(m,f(x),a,b,G,n,h)

其中,m确定F2m,f(x)为不可约多项式,a和b用于确定椭圆曲线方程,G为基点,n为G的阶,h为余因子。

6)    椭圆曲线公钥和私钥

椭圆曲线的私钥是一个随机整数,小于n;

椭圆曲线的公钥是椭圆曲线上的一个点:Q=私钥*G。

20.2  openssl的ECC实现

Openssl实现了ECC算法。ECC算法系列包括三部分:ECC算法(crypto/ec)、椭圆曲线数字签名算法ECDSA (crypto/ecdsa)以及椭圆曲线密钥交换算法ECDH(crypto/ecdh)。

研究椭圆曲线需要注意的有:

1)      数据结构

?  椭圆曲线数据结构:EC_GROUP,该结构不仅包含各个参数,还包含了各种算法;

?  点的表示:EC_POINT,其中的大数X、Y和Z为雅克比投影坐标;

?  EC_CURVE_DATA:用于内置椭圆曲线,包含了椭圆曲线的各个参数;

?  密钥结构

椭圆曲线密钥数据结构如下,定义在crypto/ec_lcl.h中,对用户是透明的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

struct ec_key_st

{

int                 version;

EC_GROUP   *group;

EC_POINT    *pub_key;

BIGNUM       *priv_key;

/* 其他项 */

}

2)   密钥生成

对照公钥和私钥的表示方法,非对称算法不同有各自的密钥生成过程。椭圆曲线的密钥生成实现在crytpo/ec/ec_key.c中。Openssl中,内置的椭圆曲线密钥生成时,首先用户需要选取一种椭圆曲线(openssl的crypto/ec_curve.c中内置实现了67种,调用EC_get_builtin_curves获取该列表),然后根据选择的椭圆曲线计算密钥生成参数group,最后根据密钥参数group来生公私钥。

3)签名值数据结构

非对称算法不同,签名的结果表示也不一样。与DSA签名值一样,ECDSA的签名结果表示为两项。ECDSA的签名结果数据结构定义在crypto/ecdsa/ecdsa.h中,如下:

typedef struct ECDSA_SIG_st

{

BIGNUM *r;

BIGNUM *s;

} ECDSA_SIG;

4)    签名与验签

对照签名结果,研究其是如何生成的。crypto/ecdsa/ ecs_sign.c实现了签名算法,crypto/ecdsa/ ecs_vrf.c实现了验签。

5)  密钥交换

研究其密钥交换是如何进行的;crypto/ecdh/ech_ossl.c实现了密钥交换算法。

文件说明:

EC_METHOD实现

ec2_smpl.c            F2m  二进制扩展域上的EC_METHOD实现;

ecp_mont.c     Fp   素数域上的EC_METHOD实现,(Montgomery 蒙哥马利)

ecp_smpl.c     Fp   素数域上的EC_METHOD实现;

ecp_nist.c       Fp   素数域上的EC_METHOD实现;

ec2_mult.c

F2m上的乘法;

ec2_smpt.c

F2m上的压缩算法;

ec_asn1.c

asn1编解码;

ec_check.c

椭圆曲线检测;

ec_curve.c

内置的椭圆曲线,

NID_X9_62_prime_field:X9.62的素数域;

NID_X9_62_characteristic_two_field:X9.62的二进制扩展域;

NIST:美国国家标准

ec_cvt.c

给定参数生成素数域和二进制扩展域上的椭圆曲线;

ec_err.c

错误处理;

ec_key.c

椭圆曲线密钥EC_KEY函数;

ec_lib.c

通用库实现,一般会调用底层的EC_METHOD方法;

ec_mult.c

This file implements the wNAF-based interleaving multi-exponentation method乘法;

ec_print.c

数据与椭圆曲线上点的相互转化;

ectest.c

测试源码,可以参考此源码学习椭圆曲线函数。

ec.h

对外头文件;

ec_lcl.h

内部头文件,数据结构一般在此定义。

20.3  主要函数

20.3.1参数设置

1)    int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,

const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)

说明:设置二进制域椭圆曲线上点point的几何坐标;

2)    int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,

const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)

说明:设置素数域椭圆曲线上点point的几何坐标;

3)   int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,const BIGNUM *x, int y_bit, BN_CTX *ctx)

说明:二进制域椭圆曲线,给定压缩坐标x和y_bit参数,设置point的几何坐标;用于将Octet-String转化为椭圆曲线上的点;

4)    int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,        const BIGNUM *x, int y_bit, BN_CTX *ctx)

说明:素数域椭圆曲线,给定压缩坐标x和y_bit参数,设置point的几何坐标;用于将Octet-String转化为椭圆曲线上的点;

5)    int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,

const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)

说明:素数域椭圆曲线group,设置点point的投影坐标系坐标x、y和z;

6)    int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)

说明:将点point设为无穷远点

7)    int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)

说明:设置二进制域椭圆曲线参数;

8)    int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)

说明:设置素数域椭圆曲线参数;

9)    int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)

说明:设置椭圆曲线的基G;generator、order和cofactor为输入参数;

10)  size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)

说明:设置椭圆曲线随机数,用于生成a和b;

11)  EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)

说明:生成二进制域上的椭圆曲线,输入参数为p,a和b;

12)  EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)

说明:生成素数域上的椭圆曲线。

20.3.2参数获取

1)    const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)

说明:获取椭圆曲线的基(G);

2)    unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)

说明:获取椭圆曲线参数的随机数,该随机数可选,用于生成椭圆曲线参数中的a和b;

3)  int EC_GROUP_get_basis_type(const EC_GROUP *group)

说明:获取二进制域多项式的类型;

4)  int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)

说明:获取椭圆曲线的余因子。cofactor为X9.62中定义的h,值为椭圆曲线点的个数/基点的阶,即:cofactor = #E(Fq)/n。

5)  int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)

说明:获取二元域椭圆曲线的三个参数,其中p可表示多项式;

6)    int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)

说明:获取素数域椭圆曲线的三个参数;

7)    int EC_GROUP_get_curve_name(const EC_GROUP *group)

说明:获取椭圆曲线名称,返回其NID;

8)    int EC_GROUP_get_degree(const EC_GROUP *group)

说明:获取椭圆曲线密钥长度。对于素数域Fp来说,是大数p的长度;对二进制域F2m来说,等于m;

9)    int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)

说明:获取椭圆曲线的阶;

10)  int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,

unsigned int *k2, unsigned int *k3)

int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)

说明:获取多项式参数;

11)   int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,BIGNUM *x, BIGNUM *y, BN_CTX *ctx)

说明:获取二进制域椭圆曲线上某个点的x和y的几何坐标;

12)  int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,        BIGNUM *x, BIGNUM *y, BN_CTX *ctx)

说明:获取素数域上椭圆曲线上某个点的x和y的几何坐标;

13)  int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)

说明:获取素数域椭圆曲线上某个点的x、y和z的投影坐标系坐标。

20.3.3转化函数

1)    EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,                           const BIGNUM *bn,EC_POINT *point,BN_CTX *ctx)

说明:将大数转化为椭圆曲线上的点;

2)    EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,                            const char *buf,EC_POINT *point,BN_CTX *ctx)

说明:将buf中表示的十六进制数据转化为椭圆曲线上的点;

3)    int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max)

说明:将大数转化为多项式的各个项;

4)    int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a)

说明:将多项式的各个项转化为大数;

5)    int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)

说明:将椭圆曲线group上点的point转化为几何坐标系;

6)    int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,

const unsigned char *buf, size_t len, BN_CTX *ctx)

说明:将buf中点数据转化为椭圆曲线上的点,len为数据长度;

7)    BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,const EC_POINT *point,                          point_conversion_form_t form,BIGNUM *ret,BN_CTX *ctx)

说明:将椭圆曲线上的点转化为大数,其中from为压缩方式,可以是POINT_CONVERSION_COMPRESSED、POINT_CONVERSION_UNCOMPRESSED或POINT_CONVERSION_HYBRID,可参考x9.62;

8)    char *EC_POINT_point2hex(const EC_GROUP *group, const EC_POINT *point,                        point_conversion_form_t form,BN_CTX *ctx)

说明:将椭圆曲线上的点转化为十六进制,并返回该结果;

9)    size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,unsigned char *buf, size_t len, BN_CTX *ctx)

说明:将椭圆曲线上的点转化为Octet-String,可分两次调用,用法见EC_POINT_point2bn的实现。

20.3.4其他函数

1)    size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)

文件:ec_curve.c

说明:获取内置的椭圆曲线。当输入参数r为NULL或者nitems为0时,返回内置椭圆曲线的个数,否则将各个椭圆曲线信息存放在r中。

示例:

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

#include

int   main()

{

EC_builtin_curve   *curves = NULL;

size_t                           crv_len = 0, n = 0;

int                               nid,ret;

EC_GROUP                 *group = NULL;

crv_len = EC_get_builtin_curves(NULL, 0);

curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);

EC_get_builtin_curves(curves, crv_len);

for (n=0;n

{

nid = curves[n].nid;

group=NULL;

group = EC_GROUP_new_by_curve_name(nid);

ret=EC_GROUP_check(group,NULL);

}

OPENSSL_free(curves);

return 0;

}

2)    const EC_METHOD *EC_GF2m_simple_method(void)

说明:返回二进制域上的方法集EC_METHOD

3)  const EC_METHOD *EC_GFp_mont_method(void)

const EC_METHOD *EC_GFp_nist_method(void)

const EC_METHOD *EC_GFp_simple_method(void)

返回素数域上的方法集EC_METHOD

4)  int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)

说明:检查椭圆曲线,成功返回1。

5)  int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)

说明:检查椭圆曲线表达式。对于素数域的椭圆曲线来说,该函数会调用ec_GFp_simple_group_check_discriminant函数,主要检查4*a^3 + 27*b^2 != 0 (mod p)。而对于二进制域的椭圆曲线,会调用ec_GF2m_simple_group_check_discriminant, 检查y^2 + x*y = x^3 + a*x^2 + b 是否是一个椭圆曲线并且 b !=0。

6)  int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)

说明:通过比较各个参数来确定两个椭圆曲线是否相等;

7)  int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)

EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)

说明:椭圆曲线拷贝函数;

9)  EC_GROUP *EC_GROUP_new_by_curve_name(int nid)

说明:根据NID获取内置的椭圆曲线;

10)  int EC_KEY_check_key(const EC_KEY *eckey)

说明:检查椭圆曲线密钥;

11)  int EC_KEY_generate_key(EC_KEY *eckey)

说明:生成椭圆曲线公私钥;

12)  int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)

说明:将椭圆曲线密钥信息输出到bio中,off为缩进量;

13)  int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)

说明:椭圆曲线上点的加法;

14)  int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)

说明:求椭圆曲线上某点a的逆元,a既是输入参数,也是输出参数;

15)  int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)

说明:判断椭圆曲线上的点point是否是无穷远点;

16)  int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)

说明:判断一个点point是否在椭圆曲线上;

17)  int     ECDSA_size

说明:获取ECC密钥大小字节数。

18)ECDSA_sign

说明:签名,返回1表示成功。

19)ECDSA_verify

说明:验签,返回1表示合法。

20)EC_KEY_get0_public_key

说明:获取公钥。

21)EC_KEY_get0_private_key

说明:获取私钥。

22)ECDH_compute_key

说明:生成共享密钥

23)EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)

说明:DER解码将椭圆曲线密钥;

24)int     i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)

说明:将椭圆曲线密钥DER编码;

20.4  编程示例

下面的例子生成两对ECC密钥,并用它做签名和验签,并生成共享密钥。

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

278

279

280

281

#include

#include

#include

#include

#include

#include

int   main()

{

EC_KEY              *key1,*key2;

EC_POINT            *pubkey1,*pubkey2;

EC_GROUP          *group1,*group2;

int                        ret,nid,size,i,sig_len;

unsigned char  *signature,digest[20];

BIO                     *berr;

EC_builtin_curve   *curves;

int                               crv_len;

char              shareKey1[128],shareKey2[128];

int                        len1,len2;

/* 构造EC_KEY数据结构 */

key1=EC_KEY_new();

if(key1==NULL)

{

printf("EC_KEY_new err!\n");

return -1;

}

key2=EC_KEY_new();

if(key2==NULL)

{

printf("EC_KEY_new err!\n");

return -1;

}

/* 获取实现的椭圆曲线个数 */

crv_len = EC_get_builtin_curves(NULL, 0);

curves = (EC_builtin_curve *)malloc(sizeof(EC_builtin_curve) * crv_len);

/* 获取椭圆曲线列表 */

EC_get_builtin_curves(curves, crv_len);

/*

nid=curves[0].nid;会有错误,原因是密钥太短

*/

/* 选取一种椭圆曲线 */

nid=curves[25].nid;

/* 根据选择的椭圆曲线生成密钥参数group */

group1=EC_GROUP_new_by_curve_name(nid);

if(group1==NULL)

{

printf("EC_GROUP_new_by_curve_name err!\n");

return -1;

}

group2=EC_GROUP_new_by_curve_name(nid);

if(group1==NULL)

{

printf("EC_GROUP_new_by_curve_name err!\n");

return -1;

}

/* 设置密钥参数 */

ret=EC_KEY_set_group(key1,group1);

if(ret!=1)

{

printf("EC_KEY_set_group err.\n");

return -1;

}

ret=EC_KEY_set_group(key2,group2);

if(ret!=1)

{

printf("EC_KEY_set_group err.\n");

return -1;

}

/* 生成密钥 */

ret=EC_KEY_generate_key(key1);

if(ret!=1)

{

printf("EC_KEY_generate_key err.\n");

return -1;

}

ret=EC_KEY_generate_key(key2);

if(ret!=1)

{

printf("EC_KEY_generate_key err.\n");

return -1;

}

/* 检查密钥 */

ret=EC_KEY_check_key(key1);

if(ret!=1)

{

printf("check key err.\n");

return -1;

}

/* 获取密钥大小 */

size=ECDSA_size(key1);

printf("size %d \n",size);

for(i=0;i<20;i++)

memset(&digest[i],i+1,1);

signature=malloc(size);

ERR_load_crypto_strings();

berr=BIO_new(BIO_s_file());

BIO_set_fp(berr,stdout,BIO_NOCLOSE);

/* 签名数据,本例未做摘要,可将digest中的数据看作是sha1摘要结果 */

ret=ECDSA_sign(0,digest,20,signature,&sig_len,key1);

if(ret!=1)

{

ERR_print_errors(berr);

printf("sign err!\n");

return -1;

}

/* 验证签名 */

ret=ECDSA_verify(0,digest,20,signature,sig_len,key1);

if(ret!=1)

{

ERR_print_errors(berr);

printf("ECDSA_verify err!\n");

return -1;

}

/* 获取对方公钥,不能直接引用 */

pubkey2 = EC_KEY_get0_public_key(key2);

/* 生成一方的共享密钥 */

len1=ECDH_compute_key(shareKey1, 128, pubkey2, key1, NULL);

pubkey1 = EC_KEY_get0_public_key(key1);

/* 生成另一方共享密钥 */

len2=ECDH_compute_key(shareKey2, 128, pubkey1, key2, NULL);

if(len1!=len2)

{

printf("err\n");

}

else

{

ret=memcmp(shareKey1,shareKey2,len1);

if(ret==0)

printf("生成共享密钥成功\n");

else

printf("生成共享密钥失败\n");

}

printf("test ok!\n");

BIO_free(berr);

EC_KEY_free(key1);

EC_KEY_free(key2);

free(signature);

free(curves);

return 0;

}

更多底层函数的使用示例可参考ec/ectest.c,特别是用户自行定义椭圆曲线参数。

转自:

http://www.pengshuo.me/2014/04/22/openssl%E7%BC%96%E7%A8%8B-%E7%AC%AC%E4%BA%8C%E5%8D%81%E7%AB%A0-%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF/

原文:http://www.cnblogs.com/testlife007/p/6704435.html

相关文章:

  • bubbles html5游戏源码,html5 canvas弹性气泡爆破 | 撒花动画
  • html 页面定位失效,html5自动定位,总是定位失败,是什么原因,求指点,多谢...
  • html照片墙效果,超酷CSS3相册照片墙动画特效
  • html select 加入css样式,css为select添加样式(无脚本)实现
  • 计算机基础知识(单选题),计算机基础知识单选题
  • 桌面上计算机删除后怎么复原,电脑桌面上出现一个图标,删掉后重启桌面又恢复了?怎么才能彻底删除?...
  • 计算机日常维护小知识,计算机日常维护小常识
  • html5按钮组水平均分,ichart.js绘制虚线、平均分虚线效果的实现代码_javascript技巧...
  • 学计算机可以考统计师吗,统计师如何备考呢?
  • html 发光字,介绍几种常见发光字的制作步骤方法
  • html中元相关元素包括,tabs_panels.html
  • 计算机专业论文周进展300字,毕业设计周进展记录模板
  • 计算机网络第3班第六章,计算机网络教程第3版彭澎第6章J课件教学.ppt
  • 计算机二级数据透视图教程,计算机二级语言数据透视表做法
  • 计算机语言符号通配符,day 15 通配符和特殊符号
  • 【mysql】环境安装、服务启动、密码设置
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Javascript弹出层-初探
  • java概述
  • jquery ajax学习笔记
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • python_bomb----数据类型总结
  • React Transition Group -- Transition 组件
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • 浮动相关
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 跨域
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 小程序测试方案初探
  • ​iOS实时查看App运行日志
  • ###C语言程序设计-----C语言学习(6)#
  • #1015 : KMP算法
  • #Linux(Source Insight安装及工程建立)
  • #QT项目实战(天气预报)
  • (175)FPGA门控时钟技术
  • (6)设计一个TimeMap
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (九)One-Wire总线-DS18B20
  • (转载)Linux 多线程条件变量同步
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .net开发引用程序集提示没有强名称的解决办法
  • @html.ActionLink的几种参数格式
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • [.net] 如何在mail的加入正文显示图片
  • [20171102]视图v$session中process字段含义
  • [2019.2.28]BZOJ4033 [HAOI2015]树上染色
  • [Golang]K-V存储引擎的学习 从零实现 (RoseDB mini版本)
  • [hibernate]基本值类型映射之日期类型
  • [Python3网络爬虫开发实战] 5.3-非关系型数据库存储
  • [Real world Haskell] 中文翻译:第一章 快速上手