


Das X.509-Zertifikat kann nicht mit der benutzerdefinierten crypto.Signer-Implementierung generiert werden
php-Editor Youzi ist hier, um Ihnen ein Problem bei der Generierung von X.509-Zertifikaten vorzustellen. Wenn Sie eine benutzerdefinierte crypto.Signer-Implementierung zum Generieren eines Zertifikats verwenden, kann es manchmal zu einem unbrauchbaren Problem kommen. Dieses Problem kann bei Entwicklern zu Verwirrung darüber führen, wie es behoben werden kann. In diesem Artikel untersuchen wir die Ursache dieses Problems und stellen einige Lösungen bereit, die Entwicklern dabei helfen, erfolgreich ihre eigenen X.509-Zertifikate zu erstellen.
Frageninhalt
Ich versuche, ein x.509-Zertifikat basierend auf dem im HSM gespeicherten RSA-Schlüsselpaar zu generieren. Ich verwende diese pkcs #11-Implementierung, um mit meinem HSM zu kommunizieren.
Da meine Kryptoobjekte in letzterem gespeichert sind, muss ich, wenn eine Operation, die ich ausführen möchte, einen privaten Schlüssel erfordert (z. B. Signieren), die Schnittstelle crypto.signer implementieren, um „auf den privaten Schlüssel zuzugreifen“. Das ist die Umsetzung.
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 }
Diese Implementierung funktioniert. Um beispielsweise eine CSR zu erstellen, benötigt die Funktion „createcertificaterequest“ den privaten Schlüssel zum Signieren der CSR (wo sich die priv any
参数),这是我提供 rsasigner
-Instanz befindet.
createcertificate ist etwas ähnlich, der Parameter pub
是要生成的证书的公钥,priv
ist der private Schlüssel des Unterzeichners.
Im folgenden Code versuche ich, ein selbstsigniertes x.509-Zertifikat zu generieren, sodass die template
和parent
Parameter laut API identisch sind.
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 }
Unabhängig vom Schlüsseltyp (rsa oder ec) gibt diese Funktion den folgenden Fehler zurück.
FATA[2022-12-22 10:48:50] x509: signature over certificate returned by signer is invalid: crypto/rsa: verification error
Dieser Fehler wird zurückgegeben, wenn die crypto.signer
Implementierung nicht korrekt abgeschlossen wurde.
Ich habe crypto.signer
implementiert, um zu versuchen, dasselbe mit Schlüsselpaaren auf elliptischen Kurven zu erreichen, aber der Fehler ist derselbe.
Ich habe auch verschiedene Hashing-Algorithmen in der sign
-Funktion ausprobiert, aber es hat nichts geändert.
Der Fehler scheint auf die Implementierung von crypto.signer
zurückzuführen zu sein, obwohl es zum Generieren von CSR verwendet werden kann.
Lösung
Obwohl ich die Lösung für dieses Problem schon vor Monaten gefunden habe, habe ich mir nie die Zeit genommen, die Antwort mitzuteilen, aber jetzt ist die Zeit gekommen.
Wenn wir direkt über pkcs #11 signieren, müssen wir das Hash-Präfix verwalten, indem wir dem Hash manuell den digestinfo-Wert voranstellen, auf den hier verwiesen wird: https://www.rfc-editor.org/rfc /rfc3447#page- 43.
Genauer gesagt ist für die Signatur rsassa-pkcs1-v1_5 die Eingabe in die eigentliche Signaturfunktion eine asn.1 der-codierte Struktur. pkcs #11 verfügt über Hash-spezifische Mechanismen (z. B. ckm_sha256_rsa_pkcs), die wissen, wie die Struktur generiert wird, aber alle gehen davon aus, dass die Daten nicht gehasht sind, was bei Kryptowährungen nicht der Fall ist. Unterzeichnerschnittstelle, daher müssen wir den generischen Mechanismus cka_rsa_pkcs verwenden, der nur Rohsignaturvorgänge ausführt. Das bedeutet, dass wir die asn.1-Struktur selbst generieren müssen, was wir tun können, indem wir einfach das richtige Präfix für alle Hashes angeben, die wir möglicherweise verwenden möchten.
Mit Hilfe des Parametersopts vom Typ crypto.signeropts können wir die Kennung einer Hash-Funktion vom Typ crypto.hash abrufen, wenn die Funktion sign() mit dem richtigen Präfix aufgerufen wird.
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 }
Der
ckm_rsa_pkcs-Mechanismus stellt Signaturen vom Typ rsassa-pkcs1-v1_5 bereit. Ich überlasse es interessierten Lesern, dieses alte Signaturschema selbst zu untersuchen, das in neuen Produkten/Software nicht mehr verwendet werden sollte.
Tatsächlich wird empfohlen, den Mechanismusckm_rsa_pkcs_pss zu verwenden, der Signaturen vom Typ rsassa-pss bereitstellt.
Ausgehend von diesem Prinzip verwende ich jetzt diese Implementierung.
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 }
Schließlich ist der verwendete
Signaturalgorithmus nicht mehr x509.sha256withrsa, x509.sha384withrsa oder x509.sha512withrsa, sondern sha256withrsapss, sha38 4withrsapss und sha512withrsapss.
Viel Spaß beim Signieren.Das obige ist der detaillierte Inhalt vonDas X.509-Zertifikat kann nicht mit der benutzerdefinierten crypto.Signer-Implementierung generiert werden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



1. Geben Sie die Webversion von OKX EUYI Exchange ein ☜☜☜☜☜☜ Klicken Sie klicken, um zu speichern. 2. Klicken Sie auf den Link der OKX Euyi Exchange -App ☜☜☜☜ Klicken Sie klicken, um zu speichern. Nach dem Eingeben der offiziellen Website bietet die Clear -Schnittstelle ein Anmelde- und Registrierungsportal. Benutzer können sich für ein vorhandenes Konto anmelden oder ein neues Konto gemäß ihrer eigenen Situation registrieren. Unabhängig davon, ob es sich um Echtzeitmarktbedingungen, die Durchführung von Transaktionen oder die Verwaltung von Vermögenswerten handelt, bietet die OKX-Webversion ein einfaches und reibungsloses Betriebserlebnis, das für Anfänger und Veteranen geeignet ist. Besuchen Sie jetzt die offizielle OKX -Website für einfache Erfahrung

Dieser Artikel enthält ein detailliertes Tutorial für Gate.IO-Registrierung, das jeden Schritt vom Zugriff auf die offizielle Website bis zur Abschluss der Registrierung abdeckt, einschließlich Ausfüllen von Registrierungsinformationen, Überprüfung, Lesen von Benutzervereinbarungen usw. Der Artikel betont auch Sicherheitsmaßnahmen nach erfolgreicher Registrierung, z.

OKX ist eine globale Digital Asset Trading Platform. Zu den Hauptfunktionen gehören: 1. Kauf und Verkauf digitaler Vermögenswerte (Spot-Handel), 2. Handel zwischen digitalen Vermögenswerten, 3. Bereitstellung von Marktbedingungen und Daten, 4. Bereitstellung diversifizierter Handelsprodukte (z. B. Derivate), 5. Bereitstellung von Wertvermögensdiensten für Vermögenswerte, 6. bequemes Asset-Management.

In diesem Artikel wird beschrieben, wie die offizielle Webversion von OK Exchange verwendet wird, um sich anzumelden. Benutzer müssen nur nach "OK Exchange Official Web -Version" in ihrem Browser suchen, auf die Login -Taste in der oberen rechten Ecke klicken und die offizielle Website eingeben und den Benutzernamen eingeben, und das Passwort einmelden. Anmeldet sich angemeldet. Registrierte Benutzer können problemlos mit Vermögenswerten umgesetzt werden. Worauf warten Sie noch? Besuchen Sie die offizielle Website von OK Exchange Now, um Ihre digitale Asset -Reise zu beginnen!

Dieser Artikel enthält eine vollständige Anleitung zur Anmeldung und Registrierung in der Binance -PC -Version. Zunächst haben wir die Schritte zur Anmeldung in Binance PC -Version ausführlich erklärt: Suchen Sie nach "Binance Official Website" im Browser, klicken Sie auf die Schaltfläche Anmeldung und geben Sie die E -Mail und das Passwort ein (aktivieren Sie 2FA, um den Überprüfungscode einzugeben), um sich anzumelden. Zweitens erklärt der Artikel den Artikel: Klicken Sie auf die Schaltfläche "Registrieren", die E -Mail -Adresse, ein starkes Passwort festlegen, und verifizieren Sie die E -Mail -Adresse, um die Registrierung zu vervollständigen. Schließlich betont der Artikel auch die Kontosicherheit und erinnert die Benutzer daran, auf den offiziellen Domainnamen, die Netzwerkumgebung und die regelmäßige Aktualisierung von Kennwörtern zu achten, um die Sicherheit der Kontos und eine bessere Verwendung verschiedener Funktionen durch die Binance -PC -Version zu gewährleisten, z. B. die Ansicht der Marktbedingungen, die Durchführung von Transaktionen und die Verwaltung von Vermögenswerten.

In diesem Artikel wird zehn bekannte Websites für die Empfehlungen im Zusammenhang mit der virtuellen Währung empfohlen, darunter Binance Academy, OKX Learn, Coingecko, Cryptoslate, Coindesk, Investopedia, Coinmarketcap, Huobi University, Coinbase Learn und Cryptocompare. Diese Websites liefern nicht nur Informationen wie Marktdaten für virtuelle Währungen, Preistrendanalyse usw., sondern auch umfangreiche Lernressourcen, einschließlich grundlegender Blockchain -Kenntnisse, Handelsstrategien sowie Tutorials und Überprüfungen verschiedener Handelsplattform -Apps, wodurch Benutzer dazu beitragen, sie besser zu verstehen und zu nutzen

Es zählt zu den Top der Welt und unterstützt alle Kategorien von Transaktionen wie Spot, Verträgen und Web3 -Geldbörsen. Es hat hohe Sicherheits- und niedrige Handhabungsgebühren. Eine umfassende Handelsplattform mit einer langen Geschichte, die für ihre Einhaltung und hohe Liquidität bekannt ist, unterstützt mehrsprachige Dienstleistungen. Der Branchenführer deckt den Währungshandel, die Hebelwirkung, die Optionen usw. mit starker Liquidität ab und unterstützt die Gebühren für die BNB -Abzüge.

Dieser Artikel listet die zehn bekannten Web3-Handelsplattformen auf, darunter Binance, OKX, Gate.io, Kraken, Bybit, Coinbase, Kucoin, Bitget, Gemini und Bitstamp. Der Artikel vergleicht die Merkmale jeder Plattform im Detail, z. B. die Anzahl der Währungen, Handelstypen (Spot, Futures, Optionen, NFT usw.), Handhabungsgebühren, Sicherheit, Compliance, Benutzergruppen usw., um den Anlegern dabei zu helfen, die am besten geeignete Handelsplattform auszuwählen. Egal, ob es sich um Hochfrequenzhändler, Vertragshandelsbegeisterte oder Investoren, die sich auf Compliance und Sicherheit konzentrieren, sie können Referenzinformationen daraus finden.
