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?
C'est parfait! Merci beaucoup. – Jayesh