2017-06-28 5 views
2

Je tente de générer des signatures ECDSA non codées «brutes» à utiliser avec une puce cryptographique. Le but est de signer quelque chose sur le PC hôte, puis de l'envoyer à la puce pour être validé. Cependant, je rencontre un petit problème. Ma compréhension est que la signature ECDSA devrait être de 64 octets (pour secp256v1). Et, quand j'utilise la puce pour générer une signature, il s'agit en effet de 64 octets. Cependant, lorsque j'utilise openssl, la signature a une longueur de 71 octets. Le début de la signature semble être une sorte de préfixe, mais je ne trouve aucune donnée sur ce que c'est.Signature OpenSSL ECDSA plus longue que prévu

Voici comment je suis en train de tout faire:

Générez la clé:

openssl ecparam -genkey -name secp256r1 -noout -out privkeyv1.pem 

Générez le "message" à signer:

echo -n "Hello World" > test.txt 

J'ai essayé deux méthodes pour signer le message. Les deux conduisent à la même sortie inattendue.

Première méthode - générer hachage SHA256 de fichier de test, le signer:

sha256sum test.txt | cut -f 1 -d " " > hash 

Connectez-vous avec pkutil

openssl pkeyutl -sign -in hash -inkey privkeyv1.pem -out test_sig_meth1 

Méthode 2: Inscrivez-vous avec OpenSSL dgst

openssl dgst -sha256 -binary -sign privkeyv1.pem -out test_sig_meth2 test.txt La question : Voici la sortie de xxd -p -c 256 test_sig_meth1: 3045022000a86fb146d5f8f6c15b962640bc2d1d928f5e0f96a5924e4db2853ec8b66fb002210085431613d0a235db1adabc090cc1062a246a78941972e298423f4b3d081b48c8

Et la sortie de xxd -p -c 256 test_sig_meth2: 30450220693732cd53d9f2ba3deae213d74cdf69a00e7325a10ddc6a4445ff2b33f95e62022100b6d2561e3afba10f95247ed05f0c59620dc0913f0d798b4148e05c4116b6384e

Comme vous pouvez le voir, ces deux méthodes génèrent quelques octets au début qui ressemblent à des octets d'en-tête (le 30450220, peut-être plus), mais je ne suis pas sûr de ce que ils sont pour ou comment les enlever. Pour référence, voici une signature de la même méthode générée sur la puce cryptographique. Si vous supprimez le remplissage de l'octet nul à la fin, il s'agit de 64 octets. La question: Comment puis-je utiliser openssl pour générer un 64 octets brut (non codé, sans entête) Signature ECDSA que je peux utiliser avec ce schéma?

+0

J'ai découvert que la sortie des deux commandes était codée en der. En utilisant asn1parse -inform der, j'ai été capable de trouver les entiers qui composent la signature (r et s) – f41lurizer

+1

Comment est-ce lié à C, s'il vous plaît? – alk

+1

Stack Overflow est un site de questions de programmation et de développement. Cette question semble être hors sujet car il ne s'agit pas de programmation ou de développement. Voir [Quels sujets puis-je poser à ce sujet?] (Http://stackoverflow.com/help/on-topic) dans le centre d'aide. Peut-être [Super User] (http://superuser.com/) ou [Unix & Linux Stack Exchange] (http://unix.stackexchange.com/) serait un meilleur endroit à demander. – jww

Répondre

1

plus de jetons, pour des raisons d'efficacité, juste en sortie le r et s comme un tableau d'octets ou une chaîne octet, où chaque r et s est la même que la taille du champ (à savoir, la taille des clés) en octets. Une autre approche consiste à produire r et s sous la forme d'une séquence de nombres, car à la fin, c'est ce que r et s sont. En utilisant ASN.1 cela devient une SEQUENCE de valeurs INTEGER.

Pour convertir à partir d'une telle séquence, vous pouvez d'abord décoder le BER en utilisant un analyseur BER pour récupérer l'entier. Ensuite, implémentez un algorithme I2OSP (entier à la primitive de flux d'octets) qui nécessite la valeur et la taille de la clé en octets/octets comme arguments. Le nombre devrait être sous forme de grand nombre entier, mais c'est très bien car les entiers codés ASN.1 BER sont aussi de grands entiers. Fondamentalement, vous devez laisser le pad avec zéro octet si le nombre est trop petit. Ensuite, vous concaténer le numéro.

Je n'entrerai pas dans OS2IP qui convertit un tableau d'octets en nombre entier.Remarque pensé que si vous l'encoder sous forme BER puis les entiers devraient pas être laissé rembourré avec zéro octets. Donc, une supercherie est encore nécessaire. Ainsi, bien que la signature change de forme, la signature reste valable; vous pouvez simplement convertir entre une forme et l'autre et la signature vérifiera toujours - aussi longtemps que vous utilisez la bonne bibliothèque pour le travail, évidemment.

+0

J'ai été capable de convertir le format des clés avec openssl asn1parse -inform der -in test_sig_meth2, qui affiche les valeurs r et s. Merci! – f41lurizer

+0

@ f41lurizer OK, mais n'oubliez pas la conversion en chaîne d'octets. Ce sera généralement juste une concaténation ... jusqu'à ce qu'une valeur plus courte vous morde. –

+0

Je ne suis pas sûr de ce que vous voulez dire en convertissant en une chaîne d'octets. Est-ce simplement un hexagone codant la chaîne, ou est-ce que je manque quelque chose? – f41lurizer