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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

《openssl 编程》之大数

發(fā)布時(shí)間:2024/4/11 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《openssl 编程》之大数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

11.1???介紹

????????????? 大數(shù)一般指的是位數(shù)很多的數(shù)。計(jì)算機(jī)表示的數(shù)的大小是有限的,精度也是有限的,它不能支持大數(shù)運(yùn)算。密碼學(xué)中采用了很多大數(shù)計(jì)算,為了讓計(jì)算機(jī)實(shí)現(xiàn)大數(shù)運(yùn)算,用戶需要定義自己的大數(shù)表示方式并及實(shí)現(xiàn)各種大數(shù)運(yùn)算。Openssl為我們提供了這些功能,主要用于非對(duì)稱算法。

11.2?? openssl大數(shù)表示

crypto/bn.h中定義了大數(shù)的表示方式,如下:

struct bignum_st

{

?????? BN_ULONG *d;

?????? int top;???

?????? int dmax;

?????? int neg;

?????? int flags;

};

各項(xiàng)意義如下:

d:BN_ULONG(應(yīng)系統(tǒng)而異,win32下為4個(gè)字節(jié))數(shù)組指針首地址,大數(shù)就存放在這里面,不過是倒放的。比如,用戶要存放的大數(shù)為12345678000(通過BN_bin2bn放入),則d的內(nèi)容如下:0x30 0x30 0x30 0x38 0x37 0x36 0x35 0x34 0x33 0x32 0x31;

top:用來(lái)指明大數(shù)占多少個(gè)BN_ULONG空間,上例中top為3。

dmax:d數(shù)組的大小。

neg:是否為負(fù)數(shù),如果為1,則是負(fù)數(shù),為0,則為正數(shù)。

flags:用于存放一些標(biāo)記,比如flags含有BN_FLG_STATIC_DATA時(shí),表明d的內(nèi)存是靜態(tài)分配的;含有BN_FLG_MALLOCED時(shí),d的內(nèi)存是動(dòng)態(tài)分配的。

11.3???大數(shù)函數(shù)

大數(shù)函數(shù)一般都能根據(jù)函數(shù)名字知道其實(shí)現(xiàn)的功能。下面簡(jiǎn)單介紹了幾個(gè)函數(shù)。

1)? BN_rand/BN_pseudo_rand

生成一個(gè)隨機(jī)的大數(shù)。

2) BN_rand_range/BN_pseudo_rand_range

生成隨機(jī)數(shù),但是給出了隨機(jī)數(shù)的范圍。

3) BN_dup

大數(shù)復(fù)制。

4)?? BN_generate_prime

生成素?cái)?shù)。

?????? 5)? int BN_add_word(BIGNUM *a, BN_ULONG w)

給大數(shù)a加上w,如果成功,返回1。

示例:

#include <openssl/bn.h>

?

int???? main()

{

int????????????????? ret;

BIGNUM??????? *a;

BN_ULONG?? w;

?

a=BN_new();

BN_one(a);

w=2685550010;

ret=BN_add_word(a,w);

if(ret!=1)

{

??????? printf("a+=w err!\n");

??????? BN_free(a);

??????? return -1;

}

BN_free(a);

return 0;

}

6)??? BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)

將內(nèi)存中的數(shù)據(jù)轉(zhuǎn)換為大數(shù),為內(nèi)存地址,len為數(shù)據(jù)長(zhǎng)度,ret為返回值。

示例:

#include <openssl/bn.h>

int main()

{

??? BIGNUM *ret1,*ret2;

?

??? ret1=BN_new();

??? ret1=BN_bin2bn("242424ab",8, ret1);

??? ret2=BN_bin2bn("242424ab",8,NULL);

??? BN_free(ret1);

??? BN_free(ret2);

??? return 0;

}

注意:輸入?yún)?shù)“242424ab”是asc碼,對(duì)應(yīng)的大數(shù)值為16進(jìn)制的0x3234323432346162

7)? int BN_bn2bin(const BIGNUM *a, unsigned char *to)

將大數(shù)轉(zhuǎn)換為內(nèi)存形式。輸入?yún)?shù)為大數(shù)a,to為輸出緩沖區(qū)地址,緩沖區(qū)需要預(yù)先分配,返回值為緩沖區(qū)的長(zhǎng)度。

示例:

#include <openssl/bn.h>

int??? main()

{

?????? BIGNUM *ret1=NULL;

?????? char bin[50],*buf=NULL;

?????? int?????????? len;

?

?????? ret1=BN_bin2bn("242424ab",8, NULL);

?????? len=BN_bn2bin(ret1,bin);

?????? len=BN_num_bytes(ret1);

?????? buf=malloc(len);

?????? len=BN_bn2bin(ret1,buf);

?????? free(buf);

?????? BN_free(ret1);

?????? return 0;

}

本例的緩沖區(qū)分配有兩種方法:靜態(tài)分配和動(dòng)態(tài)分配。動(dòng)態(tài)分配時(shí),先調(diào)用

BN_num_bytes函數(shù)獲取大數(shù)對(duì)應(yīng)的緩沖區(qū)的大小。

8)? char *BN_bn2dec(const BIGNUM *a)

將大數(shù)轉(zhuǎn)換成整數(shù)字符串。返回值中存放整數(shù)字符串,它由內(nèi)部分配空間,用戶必須在外部用OPENSSL_free函數(shù)釋放該空間。

示例:

#include <openssl/bn.h>

#include <openssl/crypto.h>

int main()

{

??? BIGNUM *ret1=NULL;

??? char?? *p=NULL;

??? int??? len=0;

?

??? ret1=BN_bin2bn("242424ab",8, NULL);

??? p=BN_bn2dec(ret1);

??? printf("%s\n",p); /* 3617571600447332706 */

??? BN_free(ret1);

OPENSSL_free(p);

??? getchar();

??? return 0;

}

??? 9) char *BN_bn2hex(const BIGNUM *a)

將大數(shù)轉(zhuǎn)換為十六進(jìn)制字符串。返回值為生成的十六進(jìn)制字符串,外部需要用OPENSSL_free函數(shù)釋放

示例:

#include <openssl/bn.h>

#include <openssl/crypto.h>

int main()

{

??? BIGNUM *ret1=NULL;

??? char?? *p=NULL;

??? int??? len=0;

?

??? ret1=BN_bin2bn("242424ab",8, NULL);

??? p=BN_bn2hex(ret1);

??? printf("%s\n",p);

??? BN_free(ret1);

??? OPENSSL_free(p);

??? getchar();

??? return 0;

}

輸出的結(jié)果為:323432346162

10)? BN_cmp

比較兩個(gè)大數(shù)。

11)BIGNUM *BN_mod_inverse(BIGNUM *in,? const BIGNUM *a,

const BIGNUM *n, BN_CTX *ctx)

計(jì)算ax=1(mod n)。

用戶使用openssl函數(shù)編程時(shí),一般用不著進(jìn)行大數(shù)運(yùn)算。BN_bin2bn、BN_hex2bn、BN_dec2bn、BN_bin2bn、BN_bn2bin、BN_bn2hex和BN_bn2dec比較常用。比如給定RSA密鑰的內(nèi)存形式,用戶可以調(diào)用BN_bin2bn來(lái)構(gòu)造RSA密鑰的大數(shù)元素來(lái)進(jìn)行RSA運(yùn)算,或者已經(jīng)生成了RSA密鑰,用戶調(diào)用BN_bn2bin將RSA各個(gè)元素導(dǎo)出到內(nèi)存中再寫入密鑰文件。

11.4???使用示例

?????? 1)示例1

#include <openssl/bn.h>

?????? #include <string.h>

?????? #include <openssl/bio.h>

???????????????????????????

?????? int??? main()

?????? {

?????? ?????? ?????? BIGNUM *bn;

???????????????????? BIO??????? *b;

???????????????????? char a[20];

???????????????????? int?????????? ret;

???????????????????????????

???????????????????? bn=BN_new();

???????????????????? strcpy(a,"32");

???????????????????? ret=BN_hex2bn(&bn,a);

???????????????????? b=BIO_new(BIO_s_file());

????????????? ?????? ret=BIO_set_fp(b,stdout,BIO_NOCLOSE);

???????????????????? BIO_write(b,"aaa",3);

???????????????????? BN_print(b,bn);

???????????????????? BN_free(bn);

???????????????????? return 0;

?????? }

?

?????? 2)示例2

????????????? 加法運(yùn)算

????????????? #include <openssl/bn.h>

????????????? #include <string.h>

????????????? #include <openssl/bio.h>

???????????????????????????

????????????? int??? main()

????????????? {

???????????????????? BIGNUM *a,*b,*add;

???????????????????? BIO ?????? *out;

???????????????????? char c[20],d[20];

???????????????????? int?????????? ret;

???????????????????????????

???????????????????? a=BN_new();

???????????????????? strcpy(c,"32");

???????????????????? ret=BN_hex2bn(&a,c);

???????????????????? b=BN_new();

???????????????????? strcpy(d,"100");

???????????????????? ret=BN_hex2bn(&b,d);

???????????????????? out=BIO_new(BIO_s_file());

???????????????????? ret=BIO_set_fp(out,stdout,BIO_NOCLOSE);

???????????????????? add=BN_new();

???????????????????? ret=BN_add(add,a,b);

???????????????????? if(ret!=1)

???????????????????? {

??????????????????????????? printf("err.\n");

??????????????????????????? return -1;

???????????????????? }

???????????????????? BIO_puts(out,"bn 0x32 + 0x100 = 0x");

???????????????????? BN_print(out,add);

???????????????????? BIO_puts(out,"\n");

???????????????????? BN_free(a);

???????????????????? BN_free(b);

???????????????????? BN_free(add);

???????????????????? BIO_free(out);

???????????????????? return 0;

????????????? }

?????? 3)? 示例3???????????

????????????? 減法運(yùn)算

????????????? #include <openssl/bn.h>

????????????? #include <string.h>

????????????? #include <openssl/bio.h>

?????????????

????????????? int??? main()

????????????? {

???????????????????? BIGNUM *a,*b,*sub;

???????????????????? BIO??????? *out;

???????????????????? char c[20],d[20];

???????????????????? int?????????? ret;

?????????????

???????????????????? a=BN_new();

???????????????????? strcpy(c,"100");

???????????????????? ret=BN_hex2bn(&a,c);

???????????????????? b=BN_new();

???????????????????? strcpy(d,"32");

???????????????????? ret=BN_hex2bn(&b,d);

???????????????????? out=BIO_new(BIO_s_file());

???????????????????? ret=BIO_set_fp(out,stdout,BIO_NOCLOSE);

???????????????????? sub=BN_new();

???????????????????? ret=BN_sub(sub,a,b);

???????????????????? if(ret!=1)

???????????????????? {

??????????????????????????? printf("err.\n");

??????????????????????????? return -1;

???????????????????? }

???????????????????? BIO_puts(out,"bn 0x100 - 0x32 = 0x");

???????????????????? BN_print(out,sub);

???????????????????? BIO_puts(out,"\n");

???????????????????? BN_free(a);

???????????????????? BN_free(b);

???????????????????? BN_free(sub);

???????????????????? BIO_free(out);

???????????????????? return 0;

?????? }

?????? 4)示例4

????????????? 乘法運(yùn)算

????????????? #include <openssl/bn.h>

????????????? #include <string.h>

????????????? #include <openssl/bio.h>

?????????????

????????????? int??? main()

????????????? {

???????????????????? BIGNUM *a,*b,*mul;

???????????????????? BN_CTX *ctx;

???????????????????? BIO??????? *out;

???????????????????? char c[20],d[20];

???????????????????? int?????????? ret;

????????????????????

???????????????????? ctx=BN_CTX_new();

???????????????????? a=BN_new();

???????????????????? strcpy(c,"32");

???????????????????? ret=BN_hex2bn(&a,c);

???????????????????? b=BN_new();

???????????????????? strcpy(d,"100");

???????????????????? ret=BN_hex2bn(&b,d);

???????????????????? out=BIO_new(BIO_s_file());

???????????????????? ret=BIO_set_fp(out,stdout,BIO_NOCLOSE);

???????????????????? mul=BN_new();

???????????????????? ret=BN_mul(mul,a,b,ctx);

???????????????????? if(ret!=1)

???????????????????? {

??????????????????????????? printf("err.\n");

??????????????????????????? return -1;

????????????? ?????? }

???????????????????? BIO_puts(out,"bn 0x32 * 0x100 = 0x");

???????????????????? BN_print(out,mul);

???????????????????? BIO_puts(out,"\n");

???????????????????? BN_free(a);

???????????????????? BN_free(b);

???????????????????? BN_free(mul);

???????????????????? BIO_free(out);

???????????????????? BN_CTX_free(ctx);

???????????????????? return 0;

?????? ?????? }

?????? 5)示例5

????????????? 除法運(yùn)算

????????????? #include <openssl/bn.h>

????????????? #include <string.h>

????????????? #include <openssl/bio.h>

?????????????

????????????? int??? main()

????????????? {

???????????????????? BIGNUM *a,*b,*div,*rem;

???????????????????? BN_CTX *ctx;

???????????????????? BIO??????? *out;

???????????????????? char c[20],d[20];

???????????????????? int?????????? ret;

?????? ?????????????

?????? ?????? ?????? ctx=BN_CTX_new();

???????????????????? a=BN_new();

???????????????????? strcpy(c,"100");

???????????????????? ret=BN_hex2bn(&a,c);

???????????????????? b=BN_new();

???????????????????? strcpy(d,"17");

???????????????????? ret=BN_hex2bn(&b,d);

???????????????????? out=BIO_new(BIO_s_file());

???????????????????? ret=BIO_set_fp(out,stdout,BIO_NOCLOSE);

???????????????????? div=BN_new();

???????????????????? rem=BN_new();

???????????????????? ret=BN_div(div,rem,a,b,ctx);

???????????????????? if(ret!=1)

???????????????????? {

??????????????????????????? printf("err.\n");

??????????????????????????? return -1;

???????????????????? }

???????????????????? BIO_puts(out,"bn 0x100 / 0x17 =0x");

???????????????????? BN_print(out,div);

???????????????????? BIO_puts(out,"\n");

???????????????????? BIO_puts(out,"bn 0x100 % 0x17 =0x");

???????????????????? BN_print(out,rem);

???????????????????? BIO_puts(out,"\n");

???????????????????? BN_free(a);

???????????????????? BN_free(b);

???????????????????? BN_free(div);

???????????????????? BN_free(rem);

???????????????????? BIO_free(out);

???????????????????? BN_CTX_free(ctx);

???????????????????? return 0;

????????????? }

?????? 6)示例6

????????????? 平方運(yùn)算

????????????? #include <openssl/bn.h>

????????????? #include <string.h>

????????????? #include <openssl/bio.h>

???????????????????????????

????????????? int??? main()

????????????? {

???????????????????? BIGNUM *a,*sqr;

???????????????????? BN_CTX *ctx;

???????????????????? BIO??????? *out;

???????????????????? char c[20];

???????????????????? int?????????? ret;

????????????????????

???????????????????? ctx=BN_CTX_new();

???????????????????? a=BN_new();

???????????????????? strcpy(c,"100");

???????????????????? ret=BN_hex2bn(&a,c);

???????????????????? sqr=BN_new();

???????????????????? out=BIO_new(BIO_s_file());

???????????????????? ret=BIO_set_fp(out,stdout,BIO_NOCLOSE);

???????????????????? ret=BN_sqr(sqr,a,ctx);

???????????????????? if(ret!=1)

???????????????????? {

??????????????????????????? printf("err.\n");

??????????????????????????? return -1;

???????????????????? }

???????????????????? BIO_puts(out,"bn 0x100 sqr? =0x");

???????????????????? BN_print(out,sqr);

???????????????????? BIO_puts(out,"\n");

???????????????????? BN_free(a);

???????????????????? BN_free(sqr);

???????????????????? BIO_free(out);

???????????????????? BN_CTX_free(ctx);

???????????????????? return 0;

????????????? }???????????

?????? 7)示例7

????????????? 次方運(yùn)算

????????????? #include <openssl/bn.h>

????????????? #include <string.h>

????????????? #include <openssl/bio.h>

???????????????????????????

????????????? int??? main()

????????????? {

???????????????????? BIGNUM *a,*exp,*b;

???????????????????? BN_CTX *ctx;

???????????????????? BIO??????? *out;

???????????????????? char c[20],d[20];

???????????????????? int?????????? ret;

????????????????????

???????????????????? ctx=BN_CTX_new();

???????????????????? a=BN_new();

???????????????????? strcpy(c,"100");

???????????????????? ret=BN_hex2bn(&a,c);

???????????????????? b=BN_new();

???????????????????? strcpy(d,"3");

???????????????????? ret=BN_hex2bn(&b,d);

???????????????????? exp=BN_new();

???????????????????? out=BIO_new(BIO_s_file());

???????????????????? ret=BIO_set_fp(out,stdout,BIO_NOCLOSE);

???????????????????? ret=BN_exp(exp,a,b,ctx);

???????????????????? if(ret!=1)

???????????????????? {

??????????????????????????? printf("err.\n");

??????????????????????????? return -1;

???????????????????? }

???????????????????? BIO_puts(out,"bn 0x100 exp 0x3? =0x");

???????????????????? BN_print(out,exp);

???????????????????? BIO_puts(out,"\n");

???????????????????? BN_free(a);

???????????????????? BN_free(b);

???????????????????? BN_free(exp);

???????????????????? BIO_free(out);

???????????????????? BN_CTX_free(ctx);

???????????????????? return 0;

????????????? }

總結(jié)

以上是生活随笔為你收集整理的《openssl 编程》之大数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。