Inhaltsverzeichnis
Frageninhalt
Lösung
Heim Backend-Entwicklung Golang Das X.509-Zertifikat kann nicht mit der benutzerdefinierten crypto.Signer-Implementierung generiert werden

Das X.509-Zertifikat kann nicht mit der benutzerdefinierten crypto.Signer-Implementierung generiert werden

Feb 10, 2024 pm 08:42 PM
加密货币

无法使用自定义 crypto.Signer 实现生成 X.509 证书

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
}
Nach dem Login kopieren

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.

). Die Funktion

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 templateparentParameter 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
}
Nach dem Login kopieren

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
Nach dem Login kopieren

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 Parameters

opts 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
}
Nach dem Login kopieren

Es funktioniert wie ein Zauber. Es gibt jedoch bessere Dinge, die man tun kann.

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 Mechanismus

ckm_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
}
Nach dem Login kopieren
Das Präfix wird also nicht mehr benötigt, aber die Entsprechung zwischen der Hash-Algorithmus-ID und dem zu verwendenden Signaturalgorithmus sowie dem zu verwendenden mgf ist erforderlich.

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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

OKX Ouyi Exchange -Webversion Eingeben Sie Link ein. Klicken Sie auf die Eingabe OKX Ouyi Exchange -Webversion Eingeben Sie Link ein. Klicken Sie auf die Eingabe Mar 31, 2025 pm 06:21 PM

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

Gate.io Registrierungs -Tutorial Gate.io Registrierungs -Tutorial Mar 31, 2025 pm 11:09 PM

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.

Wofür ist Ouyi? Was ist Ouyi Wofür ist Ouyi? Was ist Ouyi Apr 01, 2025 pm 03:18 PM

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.

OK Offizielle Portal -Web -Version OK Austauschen offizielle Webversion Login -Portal OK Offizielle Portal -Web -Version OK Austauschen offizielle Webversion Login -Portal Mar 31, 2025 pm 06:24 PM

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!

Binance Binance Computer Version Eingang Binance Binance Computer Version PC Offizielle Website Anmeldeeingang Binance Binance Computer Version Eingang Binance Binance Computer Version PC Offizielle Website Anmeldeeingang Mar 31, 2025 pm 04:36 PM

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.

Was sind die empfohlenen Websites für die Software Virtual Currency App? Was sind die empfohlenen Websites für die Software Virtual Currency App? Mar 31, 2025 pm 09:06 PM

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

Currency Trading Network Offizielle Website -Sammlung 2025 Currency Trading Network Offizielle Website -Sammlung 2025 Mar 31, 2025 pm 03:57 PM

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.

Auf welcher Plattform handelt es sich um Web3 -Transaktion? Auf welcher Plattform handelt es sich um Web3 -Transaktion? Mar 31, 2025 pm 07:54 PM

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.

See all articles