Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
/* * $Id: rsa-2.c,v 1.4 2005/02/19 16:01:53 68user Exp $ * * OpenSSL を使った RSA の実装 (2) * 素数生成はライブラリまかせ。RSA 鍵生成・暗号化・復号化は自前で版。 * * written by 68user http://X68000.q-e-d.net~68user/ */ #include #include #include #include #define BN_PUT(bn) { printf(#bn "=%s (0x%s)\n", BN_bn2dec(bn), BN_bn2hex(bn)); } #define KEYBIT_LEN 128 int main(){ unsigned char plain_buf[]="abcdefghijklmnopqrstuvwxyz1234"; ERR_load_crypto_strings(); BIGNUM *bn_e = BN_new(); BN_set_word(bn_e, 65537); BIGNUM *bn_n = BN_new(); BIGNUM *bn_d = BN_new(); BN_CTX *bn_ctx_tmp = BN_CTX_new(); { /* 素数生成 */ BIGNUM *bn_p = BN_new(); /* 素数 p */ BIGNUM *bn_q = BN_new(); /* 素数 q */ BN_generate_prime(bn_p, KEYBIT_LEN/2, 1, NULL, NULL, NULL, NULL); BN_generate_prime(bn_q, KEYBIT_LEN/2, 1, NULL, NULL, NULL, NULL); /* n = p*q * pm = p-1 * qm = q-1 * pmqm = (p-1)*(q-1) * gcd_pmqm = (p-1) と (q-1) の最大公約数 * L = (p-1) と (q-1) の最小公倍数 = (p-1)*(q-1)/gcd(p-1,q-1) */ BIGNUM *bn_pm = BN_new(); /* p-1 (p minus 1) */ BIGNUM *bn_qm = BN_new(); /* q-1 (q minus 1) */ BIGNUM *bn_pmqm = BN_new(); /* (p-1)*(q-1) */ BIGNUM *bn_gcd_pmqm = BN_new(); /* (p-1) と (q-1) の最小公倍数 */ BIGNUM *bn_L = BN_new(); /* L。(p-1) と (q-1) の最小公倍数 */ BIGNUM *bn_one = BN_new(); /* 1 */ BN_one(bn_one); BN_mul(bn_n, bn_p, bn_q, bn_ctx_tmp); BN_sub(bn_pm, bn_p, bn_one); BN_sub(bn_qm, bn_q, bn_one); BN_mul(bn_pmqm, bn_pm, bn_qm, bn_ctx_tmp); BN_gcd(bn_gcd_pmqm, bn_pm, bn_qm, bn_ctx_tmp); BN_div(bn_L, NULL, bn_pmqm, bn_gcd_pmqm, bn_ctx_tmp); BN_PUT(bn_p); BN_PUT(bn_q); BN_PUT(bn_n); BN_PUT(bn_pm); BN_PUT(bn_qm); BN_PUT(bn_pmqm); BN_PUT(bn_gcd_pmqm); BN_PUT(bn_L); /* a*x + b*y = 1 を満たす x と y (y>0) を見付ける。この y が d となる * ここでは a は L、b は e。e に大きい数を指定した場合は、逆にすべきかも。*/ { /* (x1, y1, z1) ← (1, 0, a) ここでの a は L * (x2, y2, z2) ← (0, 1, b) ここでの b は e */ BIGNUM *bn_x1 = BN_new(); BN_one(bn_x1); BIGNUM *bn_y1 = BN_new(); BN_zero(bn_y1); BIGNUM *bn_z1 = BN_new(); BN_copy(bn_z1, bn_L); BIGNUM *bn_x2 = BN_new(); BN_zero(bn_x2); BIGNUM *bn_y2 = BN_new(); BN_one(bn_y2); BIGNUM *bn_z2 = BN_new(); BN_copy(bn_z2, bn_e); BIGNUM *bn_x3 = BN_new(); BIGNUM *bn_y3 = BN_new(); BIGNUM *bn_z3 = BN_new(); BIGNUM *bn_q = BN_new(); BIGNUM *bn_tmp = BN_new(); BIGNUM *bn_zero = BN_new(); BN_zero(bn_zero); /* z2 が 0 になったらループ終了 */ while ( ! BN_is_zero(bn_z2) ){ /* q ← z1 を z2 で割った商 * (x3, y3, z3) ← (x1, y1, z1) - q * (x2, y2, z2) * (x1, y1, z1) ← (x2, y2, z2) * (x2, y2, z2) ← (x3, y3, z3) */ BN_div(bn_q, NULL, bn_z1, bn_z2, bn_ctx_tmp); BN_mul(bn_tmp, bn_q, bn_x2, bn_ctx_tmp); BN_sub(bn_x3, bn_x1, bn_tmp); BN_mul(bn_tmp, bn_q, bn_y2, bn_ctx_tmp); BN_sub(bn_y3, bn_y1, bn_tmp); BN_mul(bn_tmp, bn_q, bn_z2, bn_ctx_tmp); BN_sub(bn_z3, bn_z1, bn_tmp); BN_copy(bn_x1, bn_x2); BN_copy(bn_y1, bn_y2); BN_copy(bn_z1, bn_z2); BN_copy(bn_x2, bn_x3); BN_copy(bn_y2, bn_y3); BN_copy(bn_z2, bn_z3); } /* ここで y1 が求めたい d である。ただし d が負なら L を足して、次の候補に補正 */ BN_copy(bn_d, bn_y1); if ( BN_cmp(bn_d, bn_zero) == -1 ){ BN_add(bn_d, bn_d, bn_L); } BN_PUT(bn_e); BN_PUT(bn_d); BN_free(bn_x1); BN_free(bn_y1); BN_free(bn_z1); BN_free(bn_x2); BN_free(bn_y2); BN_free(bn_z2); BN_free(bn_x3); BN_free(bn_y3); BN_free(bn_z3); BN_free(bn_q); BN_free(bn_tmp); BN_free(bn_zero); } BN_free(bn_p); BN_free(bn_q); BN_free(bn_pm); BN_free(bn_qm); BN_free(bn_pmqm); BN_free(bn_gcd_pmqm); BN_free(bn_L); BN_free(bn_one); } char *p = plain_buf; int finished = 0; while ( ! finished && *p != '\0' ){ int i; BIGNUM *bn_chunk = BN_new(); BN_init(bn_chunk); /* 平文を鍵長のバイト数に区切る */ printf("平文: ["); for ( i=0 ; i