Jadual Kandungan
Kandungan soalan
Penyelesaian
Rumah pembangunan bahagian belakang Golang Tidak dapat menjana sijil X.509 menggunakan pelaksanaan crypto.Signer tersuai

Tidak dapat menjana sijil X.509 menggunakan pelaksanaan crypto.Signer tersuai

Feb 10, 2024 pm 08:42 PM
mata wang kripto

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

editor php Youzi di sini untuk memperkenalkan kepada anda masalah tentang penjanaan sijil X.509. Kadangkala apabila menggunakan pelaksanaan crypto.Signer tersuai untuk menjana sijil, anda mungkin menghadapi masalah yang tidak boleh digunakan. Isu ini boleh menyebabkan pembangun keliru tentang cara menyelesaikannya. Dalam artikel ini, kami akan meneroka punca masalah ini dan menyediakan beberapa penyelesaian untuk membantu pembangun berjaya menjana sijil X.509 mereka sendiri.

Kandungan soalan

Saya cuba menjana sijil x.509 berdasarkan pasangan kunci rsa yang disimpan dalam hsm. Saya menggunakan pelaksanaan pkcs #11 ini untuk berkomunikasi dengan hsm saya.

Memandangkan objek crypto saya disimpan dalam yang kedua, jika operasi yang saya ingin lakukan memerlukan kunci peribadi (seperti menandatangani), saya perlu melaksanakan antara muka crypto.signer untuk "mengakses kunci peribadi". Inilah pelaksanaannya.

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
}
Salin selepas log masuk

Pelaksanaan ini berfungsi. Contohnya, untuk mencipta csr, fungsi createcertificaterequest memerlukan kunci peribadi untuk menandatangani csr (di mana contoh priv any 参数),这是我提供 rsasigner berada.

Fungsi

createcertificate agak serupa, parameter pub是要生成的证书的公钥,priv ialah kunci peribadi penandatangan.

Dalam kod di bawah, saya cuba menjana sijil x.509 yang ditandatangani sendiri, jadi templateparentparameter adalah sama mengikut 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
}
Salin selepas log masuk

Tidak kira jenis kunci (rsa atau ec), fungsi ini mengembalikan ralat berikut.

FATA[2022-12-22 10:48:50] x509: signature over certificate returned by signer is invalid: crypto/rsa: verification error
Salin selepas log masuk

Ralat ini akan dikembalikan jika pelaksanaan crypto.signer tidak diselesaikan dengan betul.

Saya melaksanakan crypto.signer untuk mencuba melakukan perkara yang sama menggunakan pasangan kunci pada lengkung elips, tetapi ralatnya adalah sama.

Saya juga mencuba algoritma pencincangan yang berbeza dalam fungsi sign tetapi ia tidak mengubah apa-apa.

Ralat nampaknya datang dari pelaksanaan crypto.signer walaupun ia boleh digunakan untuk menjana csr.

Penyelesaian

Walaupun saya telah menemui penyelesaian untuk masalah ini beberapa bulan yang lalu, saya tidak pernah meluangkan masa untuk berkongsi jawapannya, namun, inilah masanya.

Apabila kami menandatangani terus melalui pkcs #11, kami perlu mengurus awalan cincang dengan memberi awalan cincang secara manual menggunakan nilai digestinfo yang dirujuk di sini: https://www.rfc-editor.org/rfc /rfc3447#page-43 .

Lebih tepat lagi, untuk tandatangan rsassa-pkcs1-v1_5, input kepada fungsi tandatangan sebenar ialah struktur yang dikodkan asn.1 der. pkcs #11 mempunyai mekanisme khusus cincang (cth. ckm_sha256_rsa_pkcs) yang tahu cara menjana struktur, tetapi mereka semua menganggap bahawa data tidak dicincang, yang tidak berlaku dengan mata wang kripto. antara muka penandatangan, jadi kita perlu menggunakan mekanisme cka_rsa_pkcs generik, yang hanya menjalankan operasi tandatangan mentah. Ini bermakna kita perlu menjana sendiri struktur asn.1, yang boleh kita lakukan dengan hanya menyediakan awalan yang betul untuk semua cincang yang mungkin ingin kita gunakan.

Dengan bantuan parameter opts jenis crypto.signeropts kita boleh mendapatkan semula pengecam fungsi cincang jenis crypto.hash apabila fungsi sign() dipanggil, dengan awalan yang betul digunakan.

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
}
Salin selepas log masuk

Ia berfungsi seperti azimat. Terdapat perkara yang lebih baik untuk dilakukan, walaupun.

Mekanisme

ckm_rsa_pkcs menyediakan tandatangan jenis rsassa-pkcs1-v1_5. Saya serahkan kepada pembaca yang berminat untuk menyiasat sendiri skim tandatangan lama ini, yang sepatutnya tidak lagi digunakan dalam produk/perisian baharu.

Sememangnya, adalah disyorkan untuk menggunakan mekanisme ckm_rsa_pkcs_pss, yang menyediakan tandatangan jenis rsassa-pss.

Bermula dari prinsip ini, inilah perlaksanaan yang saya gunakan sekarang.

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
}
Salin selepas log masuk

Jadi awalan tidak lagi diperlukan, tetapi korespondensi antara pengecam algoritma cincang dan algoritma tandatangan yang akan digunakan dan mgf yang akan digunakan diperlukan.

Akhirnya, dalam proses, algoritma tandatangan yang digunakan bukan lagi x509.sha256withrsa, x509.sha384withrsa atau x509.sha512withrsasha25, tetapi .8pssha2 s dan sha512withrsapss.

Selamat menandatangani.

Atas ialah kandungan terperinci Tidak dapat menjana sijil X.509 menggunakan pelaksanaan crypto.Signer tersuai. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Okx Ouyi Exchange Web Versi Masukkan pautan Klik untuk masukkan Okx Ouyi Exchange Web Versi Masukkan pautan Klik untuk masukkan Mar 31, 2025 pm 06:21 PM

1. Masukkan versi web OKX EUYI Exchange ☜☜☜☜☜☜ Klik untuk menyimpan 2. Klik pautan aplikasi OKX EUYI Exchange ☜☜☜☜ klik untuk menyimpan 3. Selepas memasukkan laman web rasmi, antara muka yang jelas menyediakan portal log masuk dan pendaftaran. Pengguna boleh memilih untuk log masuk ke akaun sedia ada atau mendaftarkan akaun baru mengikut situasi mereka sendiri. Sama ada ia melihat keadaan pasaran masa nyata, menjalankan urus niaga, atau menguruskan aset, versi Web OKX menyediakan pengalaman operasi yang mudah dan lancar, sesuai untuk pemula dan veteran. Lawati laman web rasmi OKX sekarang untuk pengalaman mudah

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

Artikel ini menyediakan tutorial pendaftaran Gate.io terperinci, yang meliputi setiap langkah daripada mengakses laman web rasmi untuk menyelesaikan pendaftaran, termasuk mengisi maklumat pendaftaran, mengesahkan, membaca perjanjian pengguna, dan lain-lain.

Apa itu Ouyi? Apa itu Ouyi Apa itu Ouyi? Apa itu Ouyi Apr 01, 2025 pm 03:18 PM

OKX adalah platform perdagangan aset digital global. Fungsi utamanya termasuk: 1. Membeli dan menjual aset digital (perdagangan tempat), 2. Dagangan antara aset digital, 3. Menyediakan syarat dan data pasaran, 4. Menyediakan produk perdagangan yang pelbagai (seperti derivatif), 5.

OK Portal Rasmi Versi Web OK Portal Log Masuk Versi Web Rasmi OK Portal Rasmi Versi Web OK Portal Log Masuk Versi Web Rasmi Mar 31, 2025 pm 06:24 PM

Artikel ini memperincikan cara menggunakan versi web rasmi OK Exchange untuk log masuk. Pengguna hanya perlu mencari "OK Exchange Versi Web Rasmi" Dalam penyemak imbas mereka, klik butang Login di sudut kanan atas selepas memasukkan laman web rasmi dan masukkan nama pengguna dan kata laluan yang mudah. pengalaman perdagangan. Apa yang anda tunggu? Lawati laman web rasmi OK Exchange sekarang untuk memulakan perjalanan aset digital anda!

Apakah laman web yang disyorkan untuk perisian aplikasi mata wang maya? Apakah laman web yang disyorkan untuk perisian aplikasi mata wang maya? Mar 31, 2025 pm 09:06 PM

Artikel ini mencadangkan sepuluh laman web cadangan aplikasi yang berkaitan dengan mata wang maya, termasuk Binance Academy, OKX Learn, Coingecko, Cryptoslate, Coindesk, Investopedia, Coinmarketcap, Huobi University, Coinbase Learn and Cryptocompare. Laman web ini bukan sahaja memberikan maklumat seperti data pasaran mata wang maya, analisis trend harga, dan lain -lain, tetapi juga menyediakan sumber pembelajaran yang kaya, termasuk pengetahuan asas blok, strategi perdagangan, dan tutorial dan ulasan pelbagai aplikasi platform perdagangan, membantu pengguna memahami dan menggunakannya

Versi Komputer Binance Binance Masuk Binance Binance Versi Komputer PC PC Laman Web Masuk Log Masuk Versi Komputer Binance Binance Masuk Binance Binance Versi Komputer PC PC Laman Web Masuk Log Masuk Mar 31, 2025 pm 04:36 PM

Artikel ini menyediakan panduan lengkap untuk log masuk dan pendaftaran pada versi PC Binance. Pertama, kami menerangkan secara terperinci langkah -langkah untuk pembalakan dalam versi PC Binance: Cari "Laman Web Rasmi Binance" Dalam penyemak imbas, klik butang Login, masukkan e -mel dan kata laluan (membolehkan 2FA untuk memasukkan kod pengesahan) untuk log masuk. Kedua, artikel menerangkan proses pendaftaran: Klik butang "Daftar" Akhirnya, artikel itu juga menekankan keselamatan akaun, mengingatkan pengguna untuk memberi perhatian kepada nama domain rasmi, persekitaran rangkaian, dan mengemas kini kata laluan secara teratur untuk memastikan keselamatan akaun dan penggunaan pelbagai fungsi yang disediakan oleh Versi PC Binance, seperti melihat keadaan pasaran, menjalankan transaksi dan mengurus aset.

Koleksi Laman Web Rasmi Rangkaian Perdagangan Mata Wang 2025 Koleksi Laman Web Rasmi Rangkaian Perdagangan Mata Wang 2025 Mar 31, 2025 pm 03:57 PM

Ia berada di antara bahagian atas di dunia, menyokong semua kategori urus niaga seperti tempat, kontrak, dan dompet Web3. Ia mempunyai yuran pengendalian keselamatan yang tinggi dan rendah. Platform perdagangan yang komprehensif dengan sejarah yang panjang, yang terkenal dengan pematuhan dan kecairan yang tinggi, menyokong perkhidmatan berbilang bahasa. Pemimpin industri meliputi perdagangan mata wang, leverage, pilihan, dan lain -lain, dengan kecairan yang kukuh dan menyokong yuran potongan BNB.

Pada platform mana urus niaga web3? Pada platform mana urus niaga web3? Mar 31, 2025 pm 07:54 PM

Artikel ini menyenaraikan sepuluh platform perdagangan Web3 yang terkenal, termasuk Binance, OKX, Gate.io, Kraken, Bybit, Coinbase, Kucoin, Bitget, Gemini dan Bitstamp. Artikel ini membandingkan ciri -ciri setiap platform secara terperinci, seperti bilangan mata wang, jenis dagangan (tempat, niaga hadapan, pilihan, NFT, dll), yuran pengendalian, keselamatan, pematuhan, kumpulan pengguna, dan lain -lain, bertujuan untuk membantu pelabur memilih platform perdagangan yang paling sesuai. Sama ada peniaga frekuensi tinggi, peminat perdagangan kontrak, atau pelabur yang memberi tumpuan kepada pematuhan dan keselamatan, mereka dapat mencari maklumat rujukan daripadanya.

See all articles