2012-04-28 21 views
0

我有一個公共指數和模數的文件。它們不是以pem或xml或der格式存儲的,它們只是以偏移量寫入的值。M2Crypto - 從非標準文件導入密鑰?

如何使用M2Crypto製作公開密鑰?我也有相同格式的私鑰。我設法使用在Stackoverflow上發佈的代碼來使用PHP生成PEM文件,但這似乎是一種非常荒謬的方式來實現它。

這不是一次性的事情,我需要能夠從這種格式的文件中讀取公開的指數和模數來檢查簽名。

回答

1

非常感謝你給Lars這裏:http://blog.oddbit.com/2011/05/09/signing-data-with-ssh-agent/

e是公開指數的一個Python longn是公開Modulus的Python long

他發佈的代碼是:

import M2Crypto 
key = M2Crypto.RSA.new_pub_key((
    M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(hex(e)[2:])), 
    M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(hex(n)[2:])), 
    )) 

六角會產生那種0xA45E的十六進制字符串,所以他的0x後只是抓住了一切。

我正在從文件中讀取密鑰,所以我沒有這麼長時間。我結束了使用:

import M2Crypto 
from binascii import hexlify 
e = f.read(4) 
n = f.read(0x80) 
key = M2Crypto.RSA.new_pub_key((
    M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(hexlify(e))), 
    M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(hexlify(n))), 
    )) 

工作就像一個魅力!

new_pub_key接受的格式,即按照該文件,必須

OpenSSL的MPINT格式 - 4字節大端位計數加位的 適當數量

我不確定這是否是一個錯字,但對於我的指數(十六進制)00010001最後是000003010001。我認爲這是一個字節數,而不是位數。他們也剝去了第一個0x00。我不知道這是標準還是因爲它是空字節。

編輯:我想我對這種格式有了一些更好的理解。

如果第一個字節是負數,則會在起始處添加一個零字節。 如果有任何前導(在開始處)零字節,它們將被剝離,除非第一個字節變爲負數,在這種情況下,只剩下一個零字節。

一些例子:

 
Unformatted: 
\x23\x24\x25\x26 
Formatted: 
\x00\x00\x00\x04\x23\x24\x25\x26 
Explanation: 
String left as is and count of bytes packed in 

Unformatted: 
\x00\x23\x55\x35 
Formatted: 
\x00\x00\x00\x03\x23\x55\x35 
Explanation: 
leading zero byte removed, byte count now 3 

Unformatted: 
\x80\x43\x55\x27 
Formatted: 
\x00\x00\x00\x05\x00\x80\x43\x55\x27 
Explanation: 
leading zero byte added because \x80 is negative 

Unformatted: 
\x00\xff\x43\x23 
Formatted: 
\x00\x00\x00\x04\x00\xff\x43\x23 
Explanation: 
Leading zero byte left because \xff is negative 

Unformatted: 
\x23\x53\66\x00 
Formatted: 
\x00\x00\x00\x04\x23\x53\66\x00 
Explanation: 
Trailing zero byte left in string