


Tidak dapat menjana sijil X.509 menggunakan pelaksanaan crypto.Signer tersuai
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 }
Pelaksanaan ini berfungsi. Contohnya, untuk mencipta csr, fungsi createcertificaterequest memerlukan kunci peribadi untuk menandatangani csr (di mana contoh priv any
参数),这是我提供 rsasigner
berada.
createcertificate agak serupa, parameter pub
是要生成的证书的公钥,priv
ialah kunci peribadi penandatangan.
Dalam kod di bawah, saya cuba menjana sijil x.509 yang ditandatangani sendiri, jadi template
和parent
parameter 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 }
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
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 }
Ia berfungsi seperti azimat. Terdapat perkara yang lebih baik untuk dilakukan, walaupun.
Mekanismeckm_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 }
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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



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

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.

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.

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!

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

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.

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.

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.
