|
公開(kāi)密鑰算法總是要基于一個(gè)數(shù)學(xué)上的難題。比如RSA 依據(jù)的是:給定兩個(gè)素?cái)?shù)p、q 很容易相乘得到n,而對(duì)n進(jìn)行因式分解卻相對(duì)困難。RSA 算法原理具體如下:
-
找出兩個(gè)“很大”的質(zhì)數(shù):P & Q
N = P * Q
M = (P – 1) * (Q – 1)
-
找出整數(shù)E,E與M互質(zhì),即除了1之外,沒(méi)有其他公約數(shù)
-
找出整數(shù)D,使得 ED 除以 M 余 1,即 (E D) % M = 1
-
經(jīng)過(guò)上述準(zhǔn)備工作之后,可以得到:
- E是公鑰,負(fù)責(zé)加密
- D是私鑰,負(fù)責(zé)解密
- N負(fù)責(zé)公鑰和私鑰之間的聯(lián)系
-
加密算法,假定對(duì)X進(jìn)行加密
-
解密算法,根據(jù)費(fèi)爾馬小定義,可以使用以下公式完成解密
接下來(lái)我們看下橢圓曲線(xiàn)上是基于什么難題的?
考慮如下等式:
K=kG [其中 K,G為Ep(a,b)上的點(diǎn),k為小于n(n是點(diǎn)G的階)的整數(shù)],不難發(fā)現(xiàn),給定k和G,根據(jù)加法法則,計(jì)算K很容易;但給定K和G,求k就相對(duì)困難了。這就是橢圓曲線(xiàn)加密算法采用的難題,我們把點(diǎn)G稱(chēng)為基點(diǎn)(base point)?,F(xiàn)在我們描述一個(gè)利用橢圓曲線(xiàn)進(jìn)行加密通信的過(guò)程:
1、用戶(hù)A選定一條橢圓曲線(xiàn)Ep(a,b),并取橢圓曲線(xiàn)上一點(diǎn),作為基點(diǎn)G。
2、用戶(hù)A選擇一個(gè)私有密鑰k,并生成公開(kāi)密鑰K=kG。
3、用戶(hù)A將Ep(a,b)和點(diǎn)K,G傳給用戶(hù)B。
4、用戶(hù)B接到信息后 ,將待傳輸?shù)拿魑木幋a到Ep(a,b)上一點(diǎn)M(編碼方法很多,這里不作討論),并產(chǎn)生一個(gè)隨機(jī)整數(shù)r。
5、用戶(hù)B計(jì)算點(diǎn)C1=M+rK;C2=rG。
6、用戶(hù)B將C1、C2傳給用戶(hù)A。
7、用戶(hù)A接到信息后,計(jì)算C1-kC2,結(jié)果就是點(diǎn)M。因?yàn)?nbsp;C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
再對(duì)點(diǎn)M進(jìn)行解碼就可以得到明文。
在這個(gè)加密通信中,如果有一個(gè)偷窺者H ,他只能看到Ep(a,b)、K、G、C1、C2,而通過(guò)K、G 求k 或通過(guò)C2、G求r 都是相對(duì)困難的,因此,H無(wú)法得到A、B間傳送的明文信息。
密碼學(xué)中,描述一條Fp上的橢圓曲線(xiàn),常用到六個(gè)參量:T=(p,a,b,n,x,y)。
(p 、a 、b) 用來(lái)確定一條橢圓曲線(xiàn),p為素?cái)?shù)域內(nèi)點(diǎn)的個(gè)數(shù),a和b是其內(nèi)的兩個(gè)大數(shù);
x,y為G基點(diǎn)的坐標(biāo),也是兩個(gè)大數(shù);
n為點(diǎn)G基點(diǎn)的階;
以上六個(gè)量就可以描述一條橢圓曲線(xiàn),有時(shí)候我們還會(huì)用到h(橢圓曲線(xiàn)上所有點(diǎn)的個(gè)數(shù)p與n相除的整數(shù)部分)。
利用這六個(gè)量T=(p,a,b,n,x,y)來(lái)定義一條橢圓曲線(xiàn)的方法如下:
- EC_GROUP *create_curve(void)
- {
- BN_CTX *ctx;
- EC_GROUP *curve;
- BIGNUM *a, *b, *p, *order, *x, *y;
- EC_POINT *generator;
-
- /* Binary data for the curve parameters */
- unsigned char a_bin[28] =
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE};
- unsigned char b_bin[28] =
- {0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,
- 0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
- 0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4};
- unsigned char p_bin[28] =
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
- unsigned char order_bin[28] =
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
- 0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D };
- unsigned char x_bin[28] =
- {0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,
- 0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
- 0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21};
- unsigned char y_bin[28] =
- {0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,
- 0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
- 0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34};
-
- /* Set up the BN_CTX */
- if(NULL == (ctx = BN_CTX_new())) handleErrors();
-
- /* Set the values for the various parameters */
- if(NULL == (a = BN_bin2bn(a_bin, 28, NULL))) handleErrors();
- if(NULL == (b = BN_bin2bn(b_bin, 28, NULL))) handleErrors();
- if(NULL == (p = BN_bin2bn(p_bin, 28, NULL))) handleErrors();
- if(NULL == (order = BN_bin2bn(order_bin, 28, NULL))) handleErrors();
- if(NULL == (x = BN_bin2bn(x_bin, 28, NULL))) handleErrors();
- if(NULL == (y = BN_bin2bn(y_bin, 28, NULL))) handleErrors();
-
- /* Create the curve */
- if(NULL == (curve = EC_GROUP_new_curve_GFp(p, a, b, ctx))) handleErrors();
-
- /* Create the generator */
- if(NULL == (generator = EC_POINT_new(curve))) handleErrors();
- if(1 != EC_POINT_set_affine_coordinates_GFp(curve, generator, x, y, ctx))
- handleErrors();
-
- /* Set the generator and the order */
- if(1 != EC_GROUP_set_generator(curve, generator, order, NULL))
- handleErrors();
-
- EC_POINT_free(generator);
- BN_free(y);
- BN_free(x);
- BN_free(order);
- BN_free(p);
- BN_free(b);
- BN_free(a);
- BN_CTX_free(ctx);
-
- return curve;
- }
關(guān)于ECC的網(wǎng)站:https://wiki./index.php/Elliptic_Curve_Cryptography
http://blog.csdn.net/dog250/article/details/5540500
2.在非對(duì)稱(chēng)密鑰體系中,用私鑰進(jìn)行簽名公鑰進(jìn)行驗(yàn)簽,但是對(duì)于ECC而言,在做簽名與驗(yàn)簽的時(shí)候除了私鑰與公鑰外還需要私鑰與公鑰對(duì)應(yīng)的橢圓曲線(xiàn),因?yàn)樵诤灻万?yàn)簽的過(guò)程中會(huì)涉及到多倍點(diǎn)的乘法,多倍點(diǎn)乘法會(huì)涉及到橢圓曲線(xiàn)。下面是OpenSSL中ECC所涉及到的ECC_KEY:
- struct ec_key_st {
- int version;
-
- EC_GROUP *group;
-
- EC_POINT *pub_key;
- BIGNUM *priv_key;
-
- unsigned int enc_flag;
- point_conversion_form_t conv_form;
-
- int references;
- int flags;
-
- EC_EXTRA_DATA *method_data;
- } /* EC_KEY */;
其中,第三個(gè)和四個(gè)參數(shù)分別是公鑰和私鑰,而第二個(gè)參數(shù)就是私鑰與公鑰對(duì)應(yīng)的曲線(xiàn),在程序中往往通過(guò)函數(shù)EC_KEY_set_group(eckey, group)對(duì)EC_KEY的grope進(jìn)行賦值(將grope賦值給eckey):
- /* create new ecdsa key (== EC_KEY) */
- if ((eckey = EC_KEY_new()) == NULL)
- goto builtin_err;
- group = EC_GROUP_new_by_curve_name(nid);
- if (group == NULL)
- goto builtin_err;
- if (EC_KEY_set_group(eckey, group) == 0)
- goto builtin_err;
- EC_GROUP_free(group);
上面這段代碼摘自O(shè)penSSL自帶的Demo:crypto\ecdsa\ecdsatest.c。
所以,對(duì)于ECC算法來(lái)說(shuō),僅僅知道公鑰和私鑰是不能調(diào)用OpenSSL自帶的簽名和驗(yàn)簽API,還需要知道對(duì)應(yīng)的橢圓曲線(xiàn):
- int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
- *sig, unsigned int *siglen, EC_KEY *eckey)
- int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
- const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
|