Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using pycrypto PKCS#7 to create a signature

Tags:

python

pkcs#7

I'm looking at the Apple docs for PassBook, and I need to:

  • create a "PKCS #7 detached signature of the manifest file".

I'd ideally like to do this with Python and I'd ideally like to use pycrypto for the task, the trouble is, I can't find any example code on the web on how to do this, there's lots of code like this:

from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA

message = 'To be encrypted'
h = SHA.new(message)

key = RSA.importKey(open('pubkey.der').read())
cipher = PKCS1_v1_5.new(key)
ciphertext = cipher.encrypt(message+h.digest())

but not knowing enough about the specifics of PKCS#7, I don't know what I need to do...

Does anyone have any ideas?

Thanks

like image 962
Chris Avatar asked Apr 29 '13 17:04

Chris


2 Answers

With a lot of help from this answer, I did it!

I know op probably moved past this, but this answer is nowhere in the internet, so here's the solution, for posterity's sake!

from OpenSSL import crypto

with open(cert) as cert_file:
    cert_buf = cert_file.read()

with open(key) as key_file:
    key_buf = key_file.read()

pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key_buf)
signcert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_buf)

bio_in = crypto._new_mem_buf(text.encode())
PKCS7_NOSIGS = 0x4  # defined in pkcs7.h
pkcs7 = crypto._lib.PKCS7_sign(signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS)  # noqa
bio_out = crypto._new_mem_buf()
crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7)
sigbytes = crypto._bio_to_string(bio_out)

Keep in mind, it uses some undocumented pyopenssl functions.

like image 166
WhyNotHugo Avatar answered Sep 28 '22 10:09

WhyNotHugo


This works for me , I was trying to sign a string for NSDL,

from OpenSSL import crypto
import base64
try:
    p12 = crypto.load_pkcs12(open("/DSCPFX.pfx", 'rb').read(), "XXXX")
    # print("p12 : ", p12)
    signcert = p12.get_certificate()
    pkey = p12.get_privatekey()

    text = "This is the text to be signed"
    bio_in = crypto._new_mem_buf(text.encode())
    PKCS7_NOSIGS = 0x4
    pkcs7 = crypto._lib.PKCS7_sign(signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS)
    bio_out = crypto._new_mem_buf()
    crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7)

    sigbytes = crypto._bio_to_string(bio_out)

    signed_data = base64.b64encode(sigbytes)
    return SUCCESS, signed_data
except Exception as err:
    print("Exception happens in sign_data and error is: ", err)
    return 0, str(err)
like image 24
Akash Raj Avatar answered Sep 28 '22 09:09

Akash Raj