2017-11-07 3 views
6

Die Eingabe: große mehrteilige signierte und verschlüsselte E-Mail (~ 10MB) mit openssl getan.M2Crypto schlechte Leistung zum Entschlüsseln und Verifizieren großer E-Mails

Entschlüsseln der Datei scheint schnell genug zu sein.

Die entschlüsselten Informationen zu überprüfen, ist MEHR als lang. Es scheint, dass es ein Problem in der M2Crypto-Bibliothek gibt. Wenn Sie den smime_load_pkcs7_bio Anruf durch eine Datei ersetzen, die den p7s schreibt und ihn mit smime_load_pkcs7 Anruf liest, ist es VIEL schneller. Aber ich möchte ein Schreiben/Lesen auf der Festplatte vermeiden (da es jetzt mein Flaschenhals ist).

Frage: Hat jemand einige Abhilfe oder Lösung für dieses Leistungsproblem?

Der Python 2.7 Code:

from M2Crypto import SMIME, X509, BIO, m2 

# read signed and encrypted file 
with open("toto.p7m", "r") as p7mFile: 
    p7mBio = BIO.File(p7mFile) 
    p7m = SMIME.PKCS7(m2.pkcs7_read_bio_der(p7mBio._ptr()), 1) 

s = SMIME.SMIME() 
# Decrypt 
s.load_key('cnt.key', 'cnt.crt', callback = lambda x : 'cnt_password.info') 
p7s = s.decrypt(p7m) 
print("Decryption ok (and fast).") 
# Verify 
p7s_bio = BIO.MemoryBuffer(p7s) 
p7, data = SMIME.smime_load_pkcs7_bio(p7s_bio) 
# MUCH FASTER !!! 
#p7, data = SMIME.smime_load_pkcs7('toto.p7s') 
print("Wow this long to load something that is in memory!") 
sk = p7.get0_signers(X509.X509_Stack()) 
if 0 == len(sk) : 
    print("ERROR : No signers.") 

s.set_x509_stack(sk) 

st = X509.X509_Store() 
st.load_info('ca.crt') 
s.set_x509_store(st) 

v = s.verify(p7, data) 
if v: 
    print("Client signature verified.") 
else: 
    print("ERROR : Signature verification FAILED.") 

generieren Schlüssel/certs

# generate control authority (key+cert) 
openssl genrsa -out ca.key 2048 -passout file:ca_password.info 
openssl req -x509 -new -nodes -key ca.key -passin file:ca_password.info -days 7300 -sha256 -extensions v3_ca -out ca.crt -subj "/C=XX/ST=Xxxxxx/L=XXXX/O=XXXXX/OU=XXXX/CN=XXX Xxxx XX" 
openssl x509 -noout -text -in ca.crt 

# generate client key + cert for CNT 
openssl genrsa -out cnt.key 2048 -passout file:cnt_password.info 
openssl req -new -key cnt.key -out cnt.csr -subj "/C=XX/ST=Xxxxxx/L=XXXX/O=XXXXX/OU=XXXX/CN=CNT xxxx" 

echo "authorityKeyIdentifier = keyid,issuer" > cnt.ext 
echo "basicConstraints = CA:FALSE" >> cnt.ext 
echo "keyUsage = digitalSignature, keyEncipherment" >> cnt.ext 
echo "subjectKeyIdentifier = hash" >> cnt.ext 

openssl x509 -req -in cnt.csr -passin file:cnt_password.info -CA ca.crt -CAkey ca.key -CAcreateserial -out cnt.crt -days 1024 -extfile cnt.ext 
openssl x509 -noout -text -in cnt.crt 


# generate client key + cert for ET 
openssl genrsa -out et.key 2048 -passout file:et_password.info 
openssl req -new -key et.key -out et.csr -subj "/C=XX/ST=Xxxxxx/L=XXXX/O=XXXXX/OU=XXXX/CN=ET xxxx" 

echo "authorityKeyIdentifier = keyid,issuer" > et.ext 
echo "basicConstraints = CA:FALSE" >> et.ext 
echo "keyUsage = digitalSignature, keyEncipherment" >> et.ext 
echo "subjectKeyIdentifier = hash" >> et.ext 

openssl x509 -req -in et.csr -passin file:et_password.info -CA ca.crt -CAkey ca.key -CAcreateserial -out et.crt -days 1024 -extfile et.ext 
openssl x509 -noout -text -in et.crt 

Testdaten generieren gehen in die E-Mail-

dd if=/dev/urandom of=sample1.jpg bs=1K count=743 
dd if=/dev/urandom of=sample2.jpg bs=1K count=3009 
dd if=/dev/urandom of=sample3.xml bs=1K count=5 
dd if=/dev/urandom of=sample4.mp4 bs=1K count=2864 

Generieren Sie die E-Mail

Die E-Mail wird von PHP-Code mit der Mail/mime.php-Bibliothek generiert.

<?php 
date_default_timezone_set('Europe/Paris'); 
require_once 'Mail/mime.php'; 

function add_fichier_2_mail(&$mime, $filename) { 
    $finfo = finfo_open(FILEINFO_MIME_TYPE); 
    $mime_type=finfo_file($finfo,$filename); 
    finfo_close($finfo); 
    $mime->addAttachment($filename, $mime_type); 
} 
$crlf = "\n"; 
$mime_mif = new Mail_mime($crlf); 
add_fichier_2_mail($mime_mif, "sample1.jpg"); 
add_fichier_2_mail($mime_mif, "sample2.jpg"); 
add_fichier_2_mail($mime_mif, "sample3.xml"); 
add_fichier_2_mail($mime_mif, "sample4.mp4"); 
$body = $mime_mif->get(); 
$hdrs=array(); 
$entete = $mime_mif->headers($hdrs); 
unset($mime_mif); 
$msg=''; 
foreach ($entete as $key=>$value) { 
    $msg.=$key.': '.$value.$crlf; 
} 
$msg.=$crlf.$crlf.$body; 
file_put_contents("email_clear.eml",$msg); 
?> 

Signieren/Verschlüsseln der E-Mail

Die E-Mail von ET privaten Schlüssel und dann verschlüsselt durch CNT öffentliche Zertifikat signiert ist. Dies gibt die folgenden Befehle:

+1

Können Sie ein Beispiel für .key/.crt und eine Dummy-E-Mail bereitstellen, auf der das Problem reproduziert wird? + libraries/python/os versions – ffeast

+0

Dies ist ein extrem dummer Hack, aber was ist mit dem Erstellen einer Ramdisk und dem Schreiben mit 'smime_load_pkcs7'? –

+0

Warum nicht. Es ist nicht die bevorzugte Lösung, aber es macht den Job. Können Sie es in einer vollständigen Antwort beschreiben? – TrapII

Antwort

1

Ich konnte dies auf meiner Maschine bestätigen, aber nicht in der Lage, herauszufinden, warum es passiert. Das Problem scheint in der BIO.MemoryBuffer Klasse zu sein ...

Als ich kommentierte, war die Problemumgehung, die sofort zu mir sprang, eine RAM-Festplatte zu erstellen und smime_load_pkcs7 dagegen zu verwenden.

Creating a ram disk on Linux

mkdir -p /mnt/tmpfs 
mount -o size=16G -t tmpfs none /mnt/tmpfs 

Dies hat zwei Vorteile: (1) Sie den fehlerhaften Code in m2crypto vermeiden und (2) können Sie vermeiden, zu oder von der Festplatte gelesen zu schreiben.