


Impossible de générer le certificat X.509 à l'aide de l'implémentation crypto.Signer personnalisée
l'éditeur php Youzi est là pour vous présenter un problème de génération de certificats X.509. Parfois, lorsque vous utilisez une implémentation crypto.Signer personnalisée pour générer un certificat, vous pouvez rencontrer un problème inutilisable. Ce problème peut laisser les développeurs perplexes quant à la manière de le résoudre. Dans cet article, nous explorerons la cause de ce problème et proposerons des solutions pour aider les développeurs à générer avec succès leurs propres certificats X.509.
Contenu de la question
J'essaie de générer un certificat x.509 basé sur une paire de clés rsa stockée dans hsm. J'utilise cette implémentation pkcs #11 pour communiquer avec mon hsm.
Comme mes objets crypto sont stockés dans ce dernier, si une opération que je souhaite effectuer nécessite une clé privée (comme la signature), je dois implémenter l'interface crypto.signer afin de "accéder à la clé privée". C'est la mise en œuvre.
type rsasigner struct { privatekey p11.privatekey publickey *rsa.publickey } func (s rsasigner) public() crypto.publickey { return s.publickey } func (s rsasigner) sign(_ io.reader, digest []byte, _ crypto.signeropts) ([]byte, error) { return s.privatekey.sign(pkcs11.mechanism{mechanism: pkcs11.ckm_sha512_rsa_pkcs}, digest) } func newrsasigner(privatekey p11.privatekey) (*rsasigner, error) { var ( modulus, publicexponent []byte err error ) // retrieve modulus n from the private key // reminder: n = p * q modulus, err = p11.object(privatekey).attribute(pkcs11.cka_modulus) if err != nil { return nil, err } // retrieve public exponent (e: "always" 65537) from the private key // reminder: φ(n) = (p - 1) * (q - 1), e such that 1 < e < φ(n) and e and φ(n) are co prime publicexponent, err = p11.object(privatekey).attribute(pkcs11.cka_public_exponent) if err != nil { return nil, err } // public key is (e, n) publickey := &rsa.publickey{ n: new(big.int).setbytes(modulus), e: int(big.newint(0).setbytes(publicexponent).uint64()), } return &rsasigner{privatekey: privatekey, publickey: publickey}, nil }
Cette implémentation fonctionne. Par exemple, pour créer un csr, la fonction createcertificaterequest nécessite la clé privée pour signer le csr (là où se trouve l'instance priv any
参数),这是我提供 rsasigner
.
createcertificate est quelque peu similaire, le paramètre pub
是要生成的证书的公钥,priv
est la clé privée du signataire.
Dans le code ci-dessous, j'essaie de générer un certificat x.509 auto-signé, donc les template
和parent
paramètres sont les mêmes selon l'API.
func (t *token) x509(id, objecttype, output string) ([]time.duration, error) { startfunction := time.now() var ( keytype int privatekeytemplate []*pkcs11.attribute privatekeyobject p11.object err error timings []time.duration signer *rsasigner cert []byte file *os.file writtenbytes int ) objecttype = strings.tolower(objecttype) if objecttype != "rsa" && objecttype != "ec" { logger.fatalf("%s: unrecognized type, it can only be equal to rsa or ec", objecttype) } switch objecttype { case "rsa": keytype = pkcs11.ckk_rsa case "ec": keytype = pkcs11.ckk_ec } // creation of the template to find the private key based on the given id (pkcs #11 attribute cka_id) privatekeytemplate = []*pkcs11.attribute{ pkcs11.newattribute(pkcs11.cka_key_type, keytype), pkcs11.newattribute(pkcs11.cka_class, pkcs11.cko_private_key), pkcs11.newattribute(pkcs11.cka_id, id), } startfindobject := time.now() privatekeyobject, err = t.session.findobject(privatekeytemplate) timings = append(timings, time.since(startfindobject)) if err != nil { return nil, err } // creation of the x.509 certificate template certtemplate := &x509.certificate{ serialnumber: big.newint(2023), subject: pkix.name{ commonname: "test", }, signaturealgorithm: x509.sha512withrsa, notbefore: time.now(), notafter: time.now().adddate(1, 0, 0), } // instantiate the rsasigner with the found private key object signer, err = newrsasigner(p11.privatekey(privatekeyobject)) if err != nil { return nil, err } startcreatecert := time.now() cert, err = x509.createcertificate(rand.reader, certtemplate, certtemplate, signer.publickey, signer) timings = append(timings, time.since(startcreatecert)) if err != nil { return nil, err } file, err = os.create(output) if err != nil { return nil, err } writtenbytes, err = file.write(cert) if err != nil { return nil, err } logger.printf("wrote %d bytes in %s", writtenbytes, output) return append(timings, time.since(startfunction)), nil }
Quel que soit le type de clé (rsa ou ec), cette fonction renvoie l'erreur suivante.
FATA[2022-12-22 10:48:50] x509: signature over certificate returned by signer is invalid: crypto/rsa: verification error
Cette erreur sera renvoyée si l'implémentation crypto.signer
n'est pas terminée correctement.
J'ai implémenté crypto.signer
pour essayer de faire la même chose en utilisant des paires de clés sur des courbes elliptiques, mais l'erreur est la même.
J'ai également essayé différents algorithmes de hachage dans la fonction sign
mais cela n'a rien changé.
L'erreur semble provenir de l'implémentation de crypto.signer
bien qu'elle puisse être utilisée pour générer du csr.
Solution
Bien que j'ai trouvé la solution à ce problème il y a des mois, je n'ai jamais pris le temps de partager la réponse, cependant, c'est le moment.
Lorsque nous signons directement via pkcs #11, nous devons gérer le préfixe de hachage en préfixant manuellement le hachage en utilisant la valeur digestinfo référencée ici : https://www.rfc-editor.org/rfc /rfc3447#page-43 .
Plus précisément, pour la signature rsassa-pkcs1-v1_5, l'entrée de la fonction de signature réelle est une structure codée asn.1 der. pkcs #11 a des mécanismes spécifiques au hachage (par exemple ckm_sha256_rsa_pkcs) qui savent comment générer la structure, mais ils supposent tous que les données ne sont pas hachées, ce qui n'est pas le cas des crypto-monnaies. signer, nous devons donc utiliser le mécanisme générique cka_rsa_pkcs, qui effectue uniquement des opérations de signature brutes. Cela signifie que nous devons générer nous-mêmes la structure asn.1, ce que nous pouvons faire en fournissant simplement le préfixe correct pour tous les hachages que nous pourrions vouloir utiliser.
À l'aide du paramètre opts de type crypto.signeropts nous pouvons récupérer l'identifiant d'une fonction de hachage de type crypto.hash lorsque la fonction sign() est appelée, avec le préfixe correct appliqué.
type signer struct { prikey p11.privatekey pubkey *rsa.publickey } var hashprefixes = map[crypto.hash][]byte{ crypto.sha256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, crypto.sha384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, crypto.sha512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, } func (s signer) public() crypto.publickey { return s.pubkey } func (s signer) sign(_ io.reader, digest []byte, opts crypto.signeropts) ([]byte, error) { return s.prikey.sign(*pkcs11.newmechanism(pkcs11.ckm_rsa_pkcs, nil), append(hashprefixes[opts.hashfunc()], digest...)) } func newsigner(key p11.privatekey) (*signer, error) { // retrieve modulus n from the private key // reminder: n = p * q modulus, err := p11.object(key).attribute(pkcs11.cka_modulus) if err != nil { return nil, err } var pubexp []byte // retrieve public exponent (e: "always" 65537) from the private key // reminder: φ(n) = (p - 1) * (q - 1), e such that 1 < e < φ(n) and e and φ(n) are co prime pubexp, err = p11.object(key).attribute(pkcs11.cka_public_exponent) if err != nil { return nil, err } // public key is (e, n) pubkey := &rsa.publickey{ n: new(big.int).setbytes(modulus), e: int(new(big.int).setbytes(pubexp).uint64()), } return &signer{prikey: key, pubkey: pubkey}, nil }
Cela fonctionne à merveille. Il y a cependant de meilleures choses à faire.
Le mécanismeckm_rsa_pkcs fournit des signatures de type rsassa-pkcs1-v1_5. Je laisse aux lecteurs intéressés le soin d'étudier par eux-mêmes cet ancien schéma de signature, qui ne devrait plus être utilisé dans les nouveaux produits/logiciels.
En effet, il est recommandé d'utiliser le mécanisme ckm_rsa_pkcs_pss, qui fournit des signatures de type rsassa-pss.
Partant de ce principe, c'est l'implémentation que j'utilise maintenant.
type Signer struct { priKey p11.PrivateKey pubKey *rsa.PublicKey } var sigAlg = map[crypto.Hash]uint{ crypto.SHA256: pkcs11.CKM_SHA256_RSA_PKCS_PSS, crypto.SHA384: pkcs11.CKM_SHA384_RSA_PKCS_PSS, crypto.SHA512: pkcs11.CKM_SHA512_RSA_PKCS_PSS, } var mgf = map[crypto.Hash]uint{ crypto.SHA256: pkcs11.CKG_MGF1_SHA256, crypto.SHA384: pkcs11.CKG_MGF1_SHA384, crypto.SHA512: pkcs11.CKG_MGF1_SHA512, } func (s Signer) Public() crypto.PublicKey { return s.pubKey } func (s Signer) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { return s.priKey.Sign(*pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_PSS, pkcs11.NewPSSParams(sigAlg[opts.HashFunc()], mgf[opts.HashFunc()], uint(opts.HashFunc().Size()))), digest) } func NewSigner(key p11.PrivateKey) (*Signer, error) { // Retrieve modulus n from the private key // Reminder: n = p * q modulus, err := p11.Object(key).Attribute(pkcs11.CKA_MODULUS) if err != nil { return nil, err } var pubExp []byte // Retrieve public exponent (e: "always" 65537) from the private key // Reminder: φ(n) = (p - 1) * (q - 1), e such that 1 < e < φ(n) and e and φ(n) are co prime pubExp, err = p11.Object(key).Attribute(pkcs11.CKA_PUBLIC_EXPONENT) if err != nil { return nil, err } // Public key is (e, n) pubKey := &rsa.PublicKey{ N: new(big.Int).SetBytes(modulus), E: int(new(big.Int).SetBytes(pubExp).Uint64()), } return &Signer{priKey: key, pubKey: pubKey}, nil }
Le préfixe n'est donc plus nécessaire, mais la correspondance entre l'identifiant de l'algorithme de hachage et l'algorithme de signature à utiliser et le mgf à utiliser est requise.
Enfin, en go, l'algorithme de signature utilisé n'est plus x509.sha256withrsa, x509.sha384withrsa ou x509.sha512withrsa, mais sha256withrsapss, 4withrsapss et sha512withrsapss.
Bonne signature.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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

1. Entrez la version Web d'OKX EUYI Exchange ☜☜☜☜☜☜ Cliquez pour enregistrer 2. Cliquez sur le lien de l'application OKX EUYI Exchange ☜☜☜☜ Cliquez pour enregistrer 3. Après être entré sur le site officiel, l'interface Efface fournit un portail de connexion et d'enregistrement. Les utilisateurs peuvent choisir de se connecter à un compte existant ou d'enregistrer un nouveau compte en fonction de leur propre situation. Qu'il s'agisse de visualiser les conditions du marché en temps réel, de mener des transactions ou de gérer des actifs, la version Web OKX offre une expérience de fonctionnement simple et fluide, adaptée aux débutants et aux anciens combattants. Visitez le site officiel OKX maintenant pour une expérience facile

Cet article fournit un didacticiel d'inscription GATE.IO détaillé, couvrant chaque étape de l'accès au site officiel à la réalisation de l'enregistrement, notamment le remplissage des informations d'enregistrement, la vérification, la lecture des accords d'utilisateurs, etc. L'article est également en vigueur les mesures de sécurité après une inscription réussie, telles que la configuration de la vérification secondaire et la réalisation de l'authentification réelle, et donne des conseils à partir des débutants pour aider les utilisateurs secondaires à démarrer en toute sécurité leur parcours numérique.

OKX est une plate-forme mondiale de trading d'actifs numériques. Ses principales fonctions incluent: 1. Achat et vente d'actifs numériques (trading au comptant), 2. Trading entre les actifs numériques, 3. Fournir des conditions et des données du marché, 4. Fournir des produits de trading diversifiés (tels que les dérivés), 5. Fournir des services à valeur ajoutée des actifs, 6. Management des actifs pratique.

Cet article détaille comment utiliser la version Web officielle d'OK Exchange pour se connecter. Les utilisateurs doivent uniquement rechercher "OK Exchange Version Web officielle" dans leur navigateur, cliquez sur le bouton de connexion dans le coin supérieur droit après être entré sur le site Web officiel, et saisir le nom d'utilisateur et le mot de passe pour se connecter. Les utilisateurs enregistrés peuvent facilement gérer les actifs, effectuer des transactions, des dépôts et retirer des fonds, etc. L'interface officielle du site Web est simple et facile à utiliser, et fournit un soutien client complet pour assurer que les utilisateurs de la douceur ne sont que des échanges sur l'organisation. Qu'attendez-vous? Visitez le site officiel d'OK Exchange maintenant pour commencer votre parcours d'actifs numériques!

Cet article fournit un guide complet de connexion et d'enregistrement sur la version Binance PC. Tout d'abord, nous avons expliqué en détail les étapes de connexion en binance PC Version: Recherchez le "site officiel de Binance" dans le navigateur, cliquez sur le bouton de connexion, entrez l'e-mail et le mot de passe (Activer 2FA pour entrer le code de vérification) pour vous connecter. Deuxièmement, l'article explique le processus d'e-mail: cliquez sur le bouton "Inscrivez-vous", remplissez l'adresse e-mail, définissez un mot de passe fort et Verifiez l'adresse de l'e-mail pour terminer l'affichage de l'inscription. Enfin, l'article met également l'accent sur la sécurité du compte, rappelant aux utilisateurs de prêter attention au nom de domaine officiel, à l'environnement réseau et à la mise à jour régulière des mots de passe pour assurer la sécurité des comptes et une meilleure utilisation des diverses fonctions fournies par la version Binance PC, telles que la visualisation des conditions du marché, la réalisation de transactions et la gestion des actifs.

Cet article recommande dix sites de recommandation d'applications liés à la monnaie virtuelle bien connus, notamment Binance Academy, Okx Learn, Coingecko, Cryptoslate, Coindesk, Investopedia, CoinmarketCap, Huobi University, Coinbase Learn et Cryptocompare. Ces sites Web fournissent non seulement des informations telles que les données du marché des devises virtuelles, l'analyse des tendances des prix, etc., mais fournissent également des ressources d'apprentissage riches, y compris les connaissances de base de la blockchain, les stratégies de trading et les didacticiels et les avis de diverses applications de plate-forme de trading, aidant les utilisateurs à mieux comprendre et à en faire usage

Il se classe parmi les meilleurs du monde, prend en charge toutes les catégories de transactions telles que Spot, Contracts et WEB3 Wallet. Il a des frais de haute sécurité et de manipulation faible. Une plate-forme de trading complète avec une longue histoire, connue pour sa conformité et sa haute liquidité, prend en charge les services multilingues. Le leader de l'industrie couvre le trading de devises, l'effet de levier, les options, etc., avec une forte liquidité et soutient les frais de déduction BNB.

Cet article répertorie les dix principales plateformes de trading Web3 bien connues, notamment Binance, Okx, Gate.io, Kraken, Bybit, Coinbase, Kucoin, Bitget, Gemini et Bitstamp. L'article compare les caractéristiques de chaque plate-forme en détail, tels que le nombre de devises, les types de trading (spot, futures, options, NFT, etc.), les frais de traitement, la sécurité, la conformité, les groupes d'utilisateurs, etc., visant à aider les investisseurs à choisir la plate-forme de négociation la plus appropriée. Qu'il s'agisse de commerçants à haute fréquence, de passionnés de trading de contrats ou d'investisseurs qui se concentrent sur la conformité et la sécurité, ils peuvent en trouver des informations de référence.
