I've got a string, a signature, and a public key, and I want to verify the signature on the string. The key looks like this:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----
I've been reading the pycrypto docs for a while, but I can't figure out how to make an RSAobj with this kind of key. If you know PHP, I'm trying to do the following:
openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA1);
Also, if I'm confused about any terminology, please let me know.
A public key contains both a modulus(very long number, can be 1024bit, 2058bit, 4096bit) and a public key exponent(much smaller number, usually equals one more than a two to some power). You need to find out how to split up that public key into the two components before you can do anything with it.
I don't know much about pycrypto but to verify a signature, take the hash of the string. Now we must decrypt the signature. Read up on modular exponentiation; the formula to decrypt a signature is
message^public exponent % modulus
. The last step is to check if the hash you made and the decrypted signature you got are the same.I think ezPyCrypto might make this a little easier. The high-level methods of the key class includes these two methods which I hope will solve your problem:verifyString - verify a string against a signatureimportKey - import public key (and possibly private key too)Rasmus points out in the comments that
verifyString
is hard-coded to use MD5, in which case ezPyCryto can't help Andrew unless he wades into its code. I defer to joeforker's answer: consider M2Crypto.More on the DER decoding.
DER encoding always follows a TLV triplet format: (Tag, Length, Value)
Tag basically tells how to interpret the bytes data in the Value field. ANS.1 does have a type system, e.g. 0x02 means integer, 0x30 means sequence (an ordered collection of one or more other type instances)
Length presentation has a special logic:
For example, say I want to encode a number of 256 bytes long, then it would be like this
Now looking at your example
It interprets as just what Rasmus Faber put in his reply
I try the code given by joeforker but it does not work. Here is my example code and it works fine.
Maybe this isn't the answer you're looking for, but if all you need is to turn the key into bits, it looks like it's Base64 encoded. Look at the
codecs
module (I think) in the standard Python library.Using M2Crypto, the above answers does not work. Here is a tested example.
And that's about it