Maison > Article > développement back-end > Pourquoi l'implémentation Go de ed25519 génère-t-elle une clé publique différente de celle attendue dans certains cas ?
Disparité de génération de clé publique ed25519
Le package cryptographique ed25519 fournit un moyen de générer des clés publiques à partir de clés privées. Cependant, les utilisateurs ont observé que la clé publique générée par l'implémentation Go ne correspond pas à la valeur attendue dans des cas d'utilisation spécifiques.
Cause fondamentale :
Cette disparité découle des différents formats utilisés pour représenter les clés privées ed25519. Le package Go utilise un format dans lequel la clé privée est représentée comme la concaténation de la graine de 32 octets et de la clé publique de 32 octets. À l'inverse, les vecteurs de test définissant les résultats attendus représentent la clé privée comme résultat de 64 octets du hachage de la graine.
Solution :
Étant donné qu'il n'est pas possible de inverser le processus de hachage, il est impossible de convertir les clés privées du vecteur de test dans un format compatible avec l'implémentation Go. Vous pouvez également créer une version modifiée de la bibliothèque Go qui prend en charge le format de clé privée alternative.
Code de bibliothèque modifié :
Les extraits de code suivants fournissent une version personnalisée de l'implémentation Go pour prendre en charge le format de clé privée alternative :
Génération de la clé publique :
<code class="go">// Generate the public key corresponding to the already hashed private // key. // // This code is mostly copied from GenerateKey in the // golang.org/x/crypto/ed25519 package, from after the SHA512 // calculation of the seed. func getPublicKey(privateKey []byte) []byte { var A edwards25519.ExtendedGroupElement var hBytes [32]byte copy(hBytes[:], privateKey) edwards25519.GeScalarMultBase(&A, &hBytes) var publicKeyBytes [32]byte A.ToBytes(&publicKeyBytes) return publicKeyBytes[:] }</code>
Signature :
<code class="go">// Calculate the signature from the (pre hashed) private key, public key // and message. // // This code is mostly copied from the Sign function from // golang.org/x/crypto/ed25519, from after the SHA512 calculation of the // seed. func sign(privateKey, publicKey, message []byte) []byte { var privateKeyA [32]byte copy(privateKeyA[:], privateKey) // we need this in an array later var messageDigest, hramDigest [64]byte h := sha512.New() h.Write(privateKey[32:]) h.Write(message) h.Sum(messageDigest[:0]) var messageDigestReduced [32]byte edwards25519.ScReduce(&messageDigestReduced, &messageDigest) var R edwards25519.ExtendedGroupElement edwards25519.GeScalarMultBase(&R, &messageDigestReduced) var encodedR [32]byte R.ToBytes(&encodedR) h.Reset() h.Write(encodedR[:]) h.Write(publicKey) h.Write(message) h.Sum(hramDigest[:0]) var hramDigestReduced [32]byte edwards25519.ScReduce(&hramDigestReduced, &hramDigest) var s [32]byte edwards25519.ScMulAdd(&s, &hramDigestReduced, &privateKeyA, &messageDigestReduced) signature := make([]byte, 64) copy(signature[:], encodedR[:]) copy(signature[32:], s[:]) return signature }</code>
Démonstration :
Le code suivant démontre l'utilisation des fonctions personnalisées pour générer la clé publique et la signature attendues :
<code class="go">privateKeyHex := "e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d" expectedPublicKey := "77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548" expectedSig := "6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08" privateKey, _ := hex.DecodeString(privateKeyHex) publicKey := getPublicKey(privateKey) fmt.Printf("Calculated key: %x\n", publicKey) fmt.Printf("Expected key: %s\n", expectedPublicKey) keyMatches := expectedPublicKey == hex.EncodeToString(publicKey) fmt.Printf("Public key matches expected: %v\n", keyMatches) buffer := []byte("4:salt6:foobar3:seqi1e1:v12:Hello World!") calculatedSig := sign(privateKey, publicKey, buffer) fmt.Printf("Calculated sig: %x\n", calculatedSig) fmt.Printf("Expected sig: %s\n", expectedSig) sigMatches := expectedSig == hex.EncodeToString(calculatedSig) fmt.Printf("Signature matches expected: %v\n", sigMatches)</code>
En intégrant ces fonctions personnalisées fonctions dans votre code, vous pouvez gérer les vecteurs de test définis dans le format de clé privée alternative et effectuer des opérations telles que la génération et la signature de clé publique sans rencontrer de résultats incompatibles.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!