2009-12-08 5 views
2

J'essaie de mettre en œuvre un schéma de vérification PKI, où une chaîne de message est signée avec une clé privée sur le serveur, la signature est stockée sur le client avec la chaîne de message. Le client vérifie ensuite la signature à l'aide d'une clé publique.Vérification PKI sur Java et Python

Les restrictions de mon environnement sont les suivantes: le serveur est Google App Engine et le client est un programme Java. J'ai joué avec des solutions Java seulement et Python seulement de vérification PKI et les ai mis au travail, cependant quand faire une opération en Python et une autre en Java pose problème, principalement en raison des restrictions de format de fichier clé et ma compréhension limitée de la terminologie cryptographique .

L'une des plus grandes limites est le support crypto dans GAE. La seule bibliothèque prise en charge est PyCrypto et cette bibliothèque ne peut pas lire les clés publiques/privées stockées au format PEM, DER ou X509. Pour autant que je puisse trouver, seul M2Crypto supporte la lecture de ces fichiers, mais il ne peut pas être utilisé dans GAE car c'est un wrapper autour d'openssl, donc pas une pure solution python. Même si je pouvais trouver un moyen de traduire les clés publiques/privées de PEM/DER/X509 au format que PyCrypto comprend, cela fonctionnera pour moi. Mais je n'ai trouvé aucun moyen de le faire. Des idées là-bas? J'ai trouvé une solution possible sous la forme de tlslite. tlslite pouvait lire une clé privée du fichier PEM et créer une signature. Voici le code.

from tlslite.utils.cryptomath import bytesToBase64 
from tlslite.utils.keyfactory import parsePEMKey 
s = open('private.pem').read() 
key = parsePEMKey(s) 

doc = 'Sample text' 
bytes = array('B') 
bytes.fromstring(doc) 

print bytesToBase64(key.sign(bytes)) 

Le code Java correspondant que j'ai utilisé pour vérifier la signature est.

String signAlgo = "SHA1WithRSAEncryption"; 

// read public key from public.der 
byte[] encodedKey = new byte[294]; // shortcut hardcoding 
getAssets().open("public.der").read(encodedKey); 

// create public key object 
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
KeyFactory kf = KeyFactory.getInstance("RSA"); 
PublicKey pk = kf.generatePublic(publicKeySpec); 

// read signature (created by python code above) 
byte[] encodedSig = new byte[345]; 
getAssets().open("signature.txt").read(encodedSig); 
byte[] decodedSig = Base64.decodeBase64(encodedSig); 

// Do verification 
Signature verifyalg = Signature.getInstance(signAlgo); 
verifyalg.initVerify(pk); 
verifyalg.update(message.getBytes()); 
Log.d(TAG, "Verif : "+verifyalg.verify(decodedSig)); 

La vérification échoue.

J'ai suspecté si le tlslite utilise l'algorithme différent pour la création de signature que ce que le code de Java attend.

J'ai donc essayé de le découvrir.

Côté python

print key.getSigningAlgorithm() 

m'a donné

pkcs1-sha1 

sur le côté Java, j'ai essayé de trouver tous les algorithmes pris en charge avec ce code:

Set<String> algos = java.security.Security.getAlgorithms("Signature"); 
for(String algo : algos) { 
    Log.d(TAG, algo); 
} 

Cela m'a donné

MD4WithRSAEncryption 
RSASSA-PSS 
SHA1withDSA 
SHA1withRSA/ISO9796-2 
1.2.840.113549.1.1.10 
SHA512withRSA/PSS 
MD5withRSA/ISO9796-2 
DSA 
SHA512WithRSAEncryption 
SHA224withRSA/PSS 
NONEWITHDSA 
SHA256withRSA/PSS 
SHA224WithRSAEncryption 
SHA256WithRSAEncryption 
SHA1withRSA/PSS 
SHA1WithRSAEncryption 
SHA384withRSA/PSS 
SHA384WithRSAEncryption 
MD5WithRSAEncryption 

J'ai essayé toutes les valeurs SHA1 du côté Java. Mais aucun n'a aidé à vérifier la signature générée par tlslite avec algo pkcs1-sha1. Une idée de cette cartographie?

Répondre

1

Ce sont des opérations différentes. En Python, vous devez utiliser hashAndSign. La valeur par défaut est SHA1.

+0

C'est parfait! Merci beaucoup. – Jayesh

1

Keyczar devrait fonctionner correctement sur App Engine, et est disponible dans les deux saveurs Java et Python.