


Apabila menandatangani sijil, pengecam kunci kebenaran disalin ke SKID
editor php Strawberry menegaskan semasa memperkenalkan sijil menandatangani bahawa pengecam kunci yang dibenarkan (SKID) memainkan peranan penting dalam proses menandatangani. Apabila sijil ditandatangani, SKID disalin ke dalam sijil dan mengenal pasti kunci dibenarkan sijil. Kewujudan pengecam ini dapat membantu memastikan ketulenan dan kesahihan sijil, dan juga memudahkan pengesahan dan pengurusan sijil seterusnya. Menyalin SKID ialah langkah yang perlu semasa menandatangani sijil, dan ia memainkan peranan penting dalam penggunaan dan penyelenggaraan sijil.
Kandungan soalan
Saya cuba tandatangan sijil menggunakan csr dan spacemonkeygo/openssl
wrapper.
Perintah openssl konsol untuk menandatangani sijil berfungsi seperti yang diharapkan dan saya mendapat sijil yang sah.
openssl x509 -req -days 365 -in cert_client.csr -ca ca/root.crt -cakey ca/root.key -set_serial 10101 -out cert_client.crt -extfile ca/extensions.cnf
Seperti yang dapat dilihat daripada tangkapan skrin, keyid skid dan issuer adalah berbeza.
Walau bagaimanapun, kod saya dalam go memberikan sijil yang salah, di mana skid mengandungi nilai tepat keyid yang mengeluarkan sijil. Ini menyebabkan nilai tidak sah untuk "Pengeluar" disalin dalam "Pengecam Kunci Kuasa": memandangkan skid adalah sama dengan keyid pengeluar, ia "berfikir" sijil dikeluarkan sendiri.
package main import ( "github.com/spacemonkeygo/openssl" "math/big" "os" "time" ) func main() { crtfilepath := filepath("ca/root.crt") keyfilepath := filepath("ca/root.key") certca, privatekeyca, err := getrootca(pathcert(crtfilepath), pathkey(keyfilepath)) if err != nil { panic(err) } serialnumber := big.newint(10101) country := "ru" organization := "some organization" commonname := "commonname" expirationdate := time.now().adddate(1, 0, 0) certinfo := &openssl.certificateinfo{ serial: serialnumber, expires: expirationdate.sub(time.now()), commonname: commonname, // will fail if these are empty or not initialized country: country, organization: organization, } // just for example. publickey is received from csr privatekeycert, err := openssl.generatersakey(2048) if err != nil { panic(err) } newcert, err := openssl.newcertificate(certinfo, openssl.publickey(privatekeycert)) if err != nil { panic(err) } err = newcert.setversion(openssl.x509_v3) if err != nil { panic(err) } // (?) must be called before adding extensions err = newcert.setissuer(certca) if err != nil { panic(err) } err = newcert.addextension(openssl.nid_basic_constraints, "critical,ca:false") if err != nil { panic(err) } err = newcert.addextension(openssl.nid_subject_key_identifier, "hash") if err != nil { panic(err) } err = newcert.addextension(openssl.nid_authority_key_identifier, "keyid:always,issuer:always") if err != nil { panic(err) } err = newcert.sign(privatekeyca, openssl.evp_sha256) if err != nil { panic(err) } pembytes, err := newcert.marshalpem() if err != nil { panic(err) } err = os.writefile("generated.crt", pembytes, os.filemode(0644)) if err != nil { panic(err) } print("done") } type filepath string type pathcert string type pathkey string func getrootca(pathcert pathcert, pathkey pathkey) (*openssl.certificate, openssl.privatekey, error) { capublickeyfile, err := os.readfile(string(pathcert)) if err != nil { return nil, nil, err } certca, err := openssl.loadcertificatefrompem(capublickeyfile) if err != nil { return nil, nil, err } caprivatekeyfile, err := os.readfile(string(pathkey)) if err != nil { return nil, nil, err } privatekeyca, err := openssl.loadprivatekeyfrompem(caprivatekeyfile) if err != nil { return nil, nil, err } return certca, privatekeyca, nil }
(Yang dijana betul)
Jika saya tidak memanggil setissuer
, skid baru dijana, tetapi sijil yang dijana masih menunjukkan "tidak sah".
Apakah yang saya lakukan salah dalam kod saya?
Kemas kini:
Saya membandingkan pelaksanaan menambah sambungan untuk 2 pembungkus: spacemonkey/go
和 pyopenssl
.
Pergi ke:
// add an extension to a certificate. // extension constants are nid_* as found in openssl. func (c *certificate) addextension(nid nid, value string) error { issuer := c if c.issuer != nil { issuer = c.issuer } var ctx c.x509v3_ctx c.x509v3_set_ctx(&ctx, c.x, issuer.x, nil, nil, 0) ex := c.x509v3_ext_conf_nid(nil, &ctx, c.int(nid), c.cstring(value)) if ex == nil { return errors.new("failed to create x509v3 extension") } defer c.x509_extension_free(ex) if c.x509_add_ext(c.x, ex, -1) <= 0 { return errors.new("failed to add x509v3 extension") } return nil }
python (beberapa komen diketepikan):
# X509Extension::__init__ def __init__( self, type_name: bytes, critical: bool, value: bytes, subject: Optional["X509"] = None, issuer: Optional["X509"] = None, ) -> None: ctx = _ffi.new("X509V3_CTX*") # A context is necessary for any extension which uses the r2i # conversion method. That is, X509V3_EXT_nconf may segfault if passed # a NULL ctx. Start off by initializing most of the fields to NULL. _lib.X509V3_set_ctx(ctx, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL, 0) # We have no configuration database - but perhaps we should (some # extensions may require it). _lib.X509V3_set_ctx_nodb(ctx) # Initialize the subject and issuer, if appropriate. ctx is a local, # and as far as I can tell none of the X509V3_* APIs invoked here steal # any references, so no need to mess with reference counts or # duplicates. if issuer is not None: if not isinstance(issuer, X509): raise TypeError("issuer must be an X509 instance") ctx.issuer_cert = issuer._x509 if subject is not None: if not isinstance(subject, X509): raise TypeError("subject must be an X509 instance") ctx.subject_cert = subject._x509 if critical: # There are other OpenSSL APIs which would let us pass in critical # separately, but they're harder to use, and since value is already # a pile of crappy junk smuggling a ton of utterly important # structured data, what's the point of trying to avoid nasty stuff # with strings? (However, X509V3_EXT_i2d in particular seems like # it would be a better API to invoke. I do not know where to get # the ext_struc it desires for its last parameter, though.) value = b"critical," + value extension = _lib.X509V3_EXT_nconf(_ffi.NULL, ctx, type_name, value) if extension == _ffi.NULL: _raise_current_error() self._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free)
Perbezaan yang jelas ialah versi api: python menerima subject
和 issuer
sebagai parameter untuk lebihan muatan. Versi pergi tidak.
Perbezaan pelaksanaan adalah seperti berikut:
- Panggil ular sawa
x509v3_ext_nconf
x509v3_ext_conf_nid
Dipanggil masuk pergi Kedua-dua fungsi boleh didapati di github.
Saya rasa tidak mungkin untuk menambah sambungan skid apabila menggunakan openspacemonkey/go-openssl dengan tandatangan ca.
Nampaknya satu-satunya cara ialah menggunakan pengikatan c secara manual dan "lakukan seperti python".
Penyelesaian
Saya melaksanakan penyelesaian yang bijak untuk menambah skid dan autoritikeyidentifier. Sijil yang dijana adalah sah. Walau bagaimanapun, memandangkan ahli certificate
结构体的 x *c.x509
tidak dieksport, satu-satunya cara untuk mengaksesnya adalah melalui petunjuk dan hantaran yang tidak selamat.
Ini bukan pendekatan yang disyorkan, tetapi cara untuk melakukannya sehingga kemas kini spacemonkey/go
(yang saya ragu akan berlaku dalam masa terdekat).
func addAuthorityKeyIdentifier(c *openssl.Certificate) error { var ctx C.X509V3_CTX C.X509V3_set_ctx(&ctx, nil, nil, nil, nil, 0) // this is ugly and very unsafe! cx509 := *(**C.X509)(unsafe.Pointer(c)) cx509Issuer := cx509 if c.Issuer != nil { cx509Issuer = *(**C.X509)(unsafe.Pointer(c.Issuer)) } ctx.issuer_cert = cx509Issuer cExtName := C.CString("authorityKeyIdentifier") defer C.free(unsafe.Pointer(cExtName)) cExtValue := C.CString("keyid:always,issuer:always") defer C.free(unsafe.Pointer(cExtValue)) extension := C.X509V3_EXT_nconf(nil, &ctx, cExtName, cExtValue) if extension == nil { return errors.New("failed to set 'authorityKeyIdentifier' extension") } defer C.X509_EXTENSION_free(extension) addResult := C.X509_add_ext(cx509, extension, -1) if addResult == 0 { return errors.New("failed to set 'authorityKeyIdentifier' extension") } return nil } func addSKIDExtension(c *openssl.Certificate) error { var ctx C.X509V3_CTX C.X509V3_set_ctx(&ctx, nil, nil, nil, nil, 0) // this is ugly and very unsafe! cx509 := *(**C.X509)(unsafe.Pointer(c)) _ = cx509 ctx.subject_cert = cx509 _ = ctx cExtName := C.CString("subjectKeyIdentifier") defer C.free(unsafe.Pointer(cExtName)) cExtValue := C.CString("hash") defer C.free(unsafe.Pointer(cExtValue)) extension := C.X509V3_EXT_nconf(nil, &ctx, cExtName, cExtValue) if extension == nil { return errors.New("failed to set 'subjectKeyIdentifier' extension") } defer C.X509_EXTENSION_free(extension) // adding itself as a subject addResult := C.X509_add_ext(cx509, extension, -1) if addResult == 0 { return errors.New("failed to set 'subjectKeyIdentifier' extension") } return nil }
Atas ialah kandungan terperinci Apabila menandatangani sijil, pengecam kunci kebenaran disalin ke SKID. 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

Artikel ini menerangkan mekanisme import pakej Go: Dinamakan import (mis., Import & quot; fmt & quot;) dan import kosong (mis., Import _ & quot; fmt & quot;). Dinamakan import membuat kandungan pakej boleh diakses, sementara import kosong hanya melaksanakan t

Artikel ini menerangkan fungsi Newflash () Beego untuk pemindahan data antara halaman dalam aplikasi web. Ia memberi tumpuan kepada menggunakan NewFlash () untuk memaparkan mesej sementara (kejayaan, kesilapan, amaran) antara pengawal, memanfaatkan mekanisme sesi. Limita

Artikel ini memperincikan penukaran yang cekap hasil pertanyaan MySQL ke dalam kepingan struct go. Ia menekankan menggunakan kaedah imbasan pangkalan data/SQL untuk prestasi optimum, mengelakkan parsing manual. Amalan terbaik untuk pemetaan medan struct menggunakan tag db dan robus

Artikel ini menunjukkan penciptaan dan stub di GO untuk ujian unit. Ia menekankan penggunaan antara muka, menyediakan contoh pelaksanaan mengejek, dan membincangkan amalan terbaik seperti menjaga mocks fokus dan menggunakan perpustakaan penegasan. Articl

Artikel ini meneroka kekangan jenis adat Go untuk generik. Ia memperincikan bagaimana antara muka menentukan keperluan jenis minimum untuk fungsi generik, meningkatkan keselamatan jenis dan kebolehgunaan semula kod. Artikel ini juga membincangkan batasan dan amalan terbaik

Artikel ini memperincikan penulisan fail yang cekap di GO, membandingkan OS.WriteFile (sesuai untuk fail kecil) dengan os.openfile dan buffered menulis (optimum untuk fail besar). Ia menekankan pengendalian ralat yang teguh, menggunakan penangguhan, dan memeriksa kesilapan tertentu.

Artikel ini membincangkan ujian unit menulis di GO, meliputi amalan terbaik, teknik mengejek, dan alat untuk pengurusan ujian yang cekap.

Artikel ini meneroka menggunakan alat pengesanan untuk menganalisis aliran pelaksanaan aplikasi GO. Ia membincangkan teknik instrumentasi manual dan automatik, membandingkan alat seperti Jaeger, Zipkin, dan OpenTelemetry, dan menonjolkan visualisasi data yang berkesan
