M2Crypto - import keys from non-standard file?

你说的曾经没有我的故事 提交于 2019-12-01 11:50:29
mowwwalker

Thank you very much to Lars here: http://blog.oddbit.com/2011/05/09/signing-data-with-ssh-agent/

e is a Python long of the public exponent. n is a Python long of the public Modulus.

The code he posted was:

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:])),
    ))

hex will generate a hex string of the sort 0xA45E, so he's just grabbing everything after the 0x.

I'm reading the key from a file, so I don't have it as a long. I ended up using:

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))),
    ))

Worked like a charm!

The accepted format of new_pub_key, as per the documentation, needs to be

OpenSSL's MPINT format - 4-byte big-endian bit-count followed by the appropriate number of bits

I'm not sure if this is a typo, but for my exponent of (in hex) 00010001 ended up being 000003010001. I think it's a byte count, not bit count. They also stripped the first 0x00. I don't know if that's standard or if because it was an empty byte.

edit: I think I have a bit of a better understanding of the format.

If the first byte is negative, a zero byte is added to the beginning. If there are any leading (at the beginning) zero bytes, they are stripped unless the first byte would become negative, in which case, only one zero byte is left.

Some examples:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!