2016-07-11 9 views
0

opensslを使用して鍵のblobを作成しました。 opensslを使用して暗号化操作(暗号化、復号化、署名、検証など)にkeyblobを使用する必要があります。そのコードはプラットフォームに依存しません。暗号操作にKeyBlob(バイト形式で格納)を使用する可能性があります。

// Assume that "private_key" is having private key 
// keyBlob is a byte array of size 2048 
// e,n,p,q,dmp1,dmq1,iqmp,d are of type BIGNUM* and initialized with NULL  

RSA* rsa = new RSA(); 

rsa = EVP_PKEY_get1_RSA (private_key); 
if (NULL == rsa) 
{ 
    hResult = errno; 
    printf("\n\tError:EVP_PKEY_get1_RSA failed\n\n"); 
    break; 
} // if 
else 
{ 
    //printf("\n\tRSA private key generated successfully\n\n"); 
} // else 

e = rsa->e; 
n = rsa->n; 
p = rsa->p; 
q = rsa->q; 
dmp1 = rsa->dmp1; 
dmq1 = rsa->dmq1; 
iqmp = rsa->iqmp; 
d = rsa->d; 
version = rsa->version; 

// Convert from bignum to binary. 
// Modulus (n) 
modulus = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(n, modulus); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Exponent1 (dmp1) 
exponent1 = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(dmp1, exponent1); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Exponent2 (dmq1) 
exponent2 = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(dmq1, exponent2); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Prime1 (p) 
prime1 = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(p, prime1); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Prime2 (q) 
prime2 = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(q, prime2); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Public exponent (e) 
public_exponent = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(e, public_exponent); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Private exponent (d) 
private_exponent = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 
iResult = BN_bn2bin(d, private_exponent); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

// Coefficient (iqmp) 
coefficient = (unsigned char*)calloc(RSA_size(rsa), sizeof(unsigned char)); 

iResult = BN_bn2bin(iqmp, coefficient); 
if(!iResult) 
{ 
    hResult = errno; 
    printf("\n\tError:BN_bn2bin failed\n\n"); 
    break; 
} // if 

RSAPUBKEY* rsapubkey = (RSAPUBKEY*)(keyBlob + sizeof(BLOBHEADER)); 

rsapubkey->bitlen = MAX_CERT_LEN; 
rsapubkey->magic = 0x32415352; // 0x0032a400 
rsapubkey->pubexp = *public_exponent; 

int m1 = rsapubkey->bitlen/8 + 20; 

unsigned int i = 0; 

// Convert all the components from Big Endian to Little Endian 
for(i = 0; i < (rsapubkey->bitlen/8); i++) 
{ 
    keyBlob[m1 - 1 - i] = modulus[i]; 
} // for 

int p1 = rsapubkey->bitlen/16 + m1; 

for (i = 0; i < (rsapubkey->bitlen/16); i++) 
{ 
    keyBlob[p1 - 1 - i] = prime1[i]; 
} // for 

int p2 = rsapubkey->bitlen/16 + p1; 

for(i = 0; i < (rsapubkey->bitlen/16); i++) 
{ 
    keyBlob[p2- 1 - i] = prime2[i]; 
} // for 

int e1 = rsapubkey->bitlen/16 + p2; 

for(i = 0; i < (rsapubkey->bitlen/16); i++) 
{ 
    keyBlob[e1 - 1 - i] = exponent1[i]; 
} // for 

int e2 = rsapubkey->bitlen/16 + e1; 

for (i = 0; i < (rsapubkey->bitlen/16); i++) 
{ 
    keyBlob[e2 - 1 - i] = exponent2[i]; 
} // for 

int c1 = rsapubkey->bitlen/16 + e2; 

for (i = 0; i < (rsapubkey->bitlen/16); i++) 
{ 
    keyBlob[c1 - 1 - i] = coefficient[i]; 
} // for 

int d1 = rsapubkey->bitlen/8 + c1; 

for (i = 0; i < (rsapubkey->bitlen/8); i++) 
{ 
    keyBlob[d1 - 1 - i] = private_exponent[i]; 
} // for 

/* 
    FYI 
    struct _RSAPUBKEY { 
      DWORD magic;     // Has to be RSA1 
      DWORD bitlen;     // # of bits in modulus 
      DWORD pubexp;     // public exponent 
              // Modulus data follows 
    } RSAPUBKEY 

    and 

    struct _PUBLICKEYSTRUC { 
      BYTE bType; 
      BYTE bVersion; 
      WORD reserved; 
      ALG_ID aiKeyAlg; 
    } BLOBHEADER, PUBLICKEYSTRUC; 
*/  
these structures already in wincrypt.h(in windows), but for linux we need add manually.. 

ここでkeyblobは "keyBlob"に格納されます。 ここまでうまく動作します。 他の関数では、このkeyBlobを(rsa apiを使用して)暗号操作に使用する方法を説明します。 は、バイト配列に...

RSA* rsa = new RSA(); 
... 

e = rsa->e; 
n = rsa->n; 
p = rsa->p; 
q = rsa->q; 
dmp1 = rsa->dmp1; 
dmq1 = rsa->dmq1; 
iqmp = rsa->iqmp; 

...私はこれらをひそかすることが期待道を信じて、我々は暗号化

+0

コードを表示し、問題があることを明記してください。 – jww

+0

上記の編集済みの説明を確認してください – Srujan

+0

あなたの問題は何ですか?仮説的なものではなく、本当の問題を述べてください。また、 'RSAPUBKEY'構造と' BLOBHEADER'構造を表示する必要があります。 – jww

答えて

0

ためRSA_public_encryptを使用しているとしましょうBN_num_bytes and BN_bn2binを使用することです:

int len, res; 

len = BN_num_bytes(n); 
unsigned char* n_arr = OpenSSL_malloc(len); 
ASSERT(n_arr != NULL); 
res = BN_bn2bin(n, n_arr); 
ASSERT(res == len); 

len = BN_num_bytes(e); 
unsigned char* e_arr = OpenSSL_malloc(len); 
ASSERT(e_arr != NULL); 
res = BN_bn2bin(e, e_arr); 
ASSERT(res == len); 

... 

OpenSSL_free(n_arr); 
OpenSSL_free(e_arr); 

バイト配列はビッグエンディアンであることに注意してください。

また、EVP_PKEY*RSA*を解放する必要があります。 1EVP_PKEY_get1_RSAの場合、RSA*の参照カウントがバンプされているため、RSA_freeを呼び出す必要があります。 A 0は、カウントがインクリメントされなかったことを意味します。したがって、*_freeは必要ありません。



が直接RSA*を使用して...私たちは、暗号化のためのRSA_public_encryptを使用しているとしましょう。

RSAPUBKEY* rsapubkey = (RSAPUBKEY*)(keyBlob + sizeof(BLOBHEADER));

これはMS-CAPIある場合は、reverse the byte arraysする必要があります。しかし、そのMSのCAPIは私には明らかではありません。

私はあなたの問題がBNが抽出され変換される方法であると推測しています。しかし、それだけの推測では、あなたが「それを使う」以外に何をしようとしているのかがわからないからです。

+0

いいえ、MS-CAPIはありません。私はopensslを使ってこれらを試しています。そのため、コードはどのプラットフォームでも動作します。 – Srujan

+0

また、同じ機能で暗号化を実行する場合、RSA *を直接使用することもできます。しかし、他の関数で操作しています(keyblobとデータをパラメータとして渡すことによって) – Srujan

関連する問題