Maison >développement back-end >Golang >Comment ajouter le DirName et le numéro de série à l'identifiant de clé d'autorisation X509v3
l'éditeur php Strawberry vous présentera comment ajouter DirName et le numéro de série à l'identifiant de la clé d'autorisation X509v3. Dans les communications réseau, un identifiant de clé d'autorisation (X509v3) est un certificat numérique utilisé pour vérifier l'identité de la partie communicante. DirName fait référence au nom du titulaire du certificat, tandis que le numéro de série est le numéro utilisé pour identifier de manière unique le certificat. En ajoutant DirName et numéro de série, la lisibilité et le caractère unique du certificat peuvent être augmentés, et la sécurité et la fiabilité de la communication peuvent être améliorées. Ensuite, nous expliquerons en détail comment procéder.
J'essaie de générer un certificat client en utilisant openssl et go code. J'ai un script openssl qui génère un certificat avec l'extension requise et je souhaite obtenir le même résultat en utilisant le code go.
Le fichier options.ext utilisé par openssl contient les extensions suivantes :
basicconstraints=ca:false authoritykeyidentifier=keyid,issuer subjectkeyidentifier=hash keyusage=digitalsignature extendedkeyusage=clientauth
Le script openssl que j'ai actuellement est le suivant :
openssl req \ -newkey rsa:2048 \ -keyout cert.crt \ -out cert.csr \ -nodes \ -sha256 openssl x509 \ -req \ -ca ca.crt \ -cakey ca.key \ -in cert.csr \ -out cert.crt \ -days 365 \ -cacreateserial \ -extfile options.ext \ -sha256
Après avoir généré le certificat, je peux visualiser ses détails à l'aide de la commande suivante :
openssl x509 -in cert.crt -text -noout
Le certificat généré a la structure suivante :
certificate: data: version: 3 (0x2) serial number: xx:xx:xx:xx:xx:xx:xx:xx signature algorithm: sha256withrsaencryption issuer: cn=xxx validity not before: jan 1 00:00:00 2023 gmt not after : jan 1 00:00:00 2024 gmt subject: cn=xxx subject public key info: public key algorithm: rsaencryption rsa public-key: (2048 bit) modulus: ... exponent: 65537 (0x10001) x509v3 extensions: x509v3 basic constraints: ca:false x509v3 authority key identifier: dirname:cn=xxx serial:xx:xx:xx:xx:xx:xx:xx:xx x509v3 subject key identifier: ... x509v3 key usage: digital signature x509v3 extended key usage: tls web client authentication signature algorithm: sha256withrsaencryption
Cela devrait ressembler à ceci :
x509v3 authority key identifier: dirname:cn=xxx serial:xx:xx:xx:xx:xx:xx:xx:xx
Dans mon code go, j'utilise le package x509 pour générer le certificat. Cependant, je ne sais pas comment configurer l'extension d'identifiant de clé d'autorisation x509v3. Voici la partie pertinente de mon code go :
import ( "crypto/rand" "crypto/rsa" "crypto/sha1" "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "os" "time" ) ... var cacertificate *x509.certificate var caprivatekey *rsa.privatekey var authoritykeyidentifiervalue []byte // how to write this? template := &x509.certificate{ subject: pkix.name{ commonname: "xxx", }, extraextensions: []pkix.extension{ { id: asn1.objectidentifier{2, 5, 29, 35}, value: authoritykeyidentifiervalue, }, }, keyusage: x509.keyusagedigitalsignature, extkeyusage: []x509.extkeyusage{x509.extkeyusageclientauth}, notbefore: time.now(), notafter: time.now().adddate(0, 0, 365), isca: false, basicconstraintsvalid: true, } privatekey, err := rsa.generatekey(rand.reader, 2048) if err != nil { // err } certificatebytes, err := x509.createcertificate(rand.reader, template, cacertificate, &privatekey.publickey, caprivatekey) if err != nil { // err } // out
Comment ajouter le nom de répertoire et le numéro de série à l'identifiant de la clé d'autorisation x509v3 ?
Quand j'essaye ceci :
var capublickeybytes []byte publickeyhash := (sha1.sum(capublickeybytes))[:] var dirname string authoritykeyidentifiervalue := []byte{0x30, len(publickeyhash)} authoritykeyidentifiervalue = append(authoritykeyidentifiervalue, publickeyhash...) authoritykeyidentifiervalue = append(authoritykeyidentifiervalue, 0x80, len(dirname)) authoritykeyidentifiervalue = append(authoritykeyidentifiervalue, []byte(dirname)...) ...
Le résultat est :
X509v3 Authority Key Identifier: 0....0...<....).!.r[..F.....".hCN=xxx.....$...D
authoritykeyidentifiervalue
可以使用 asn1.marshal 生成。下面的演示根据 rfc 5280定义了 struct authkeyid
> et utilisez cette structure pour générer la valeur :
package main import ( "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "encoding/hex" "encoding/pem" "fmt" "math/big" ) // rfc 5280, a.2. implicitly tagged module, 1988 syntax // // authoritykeyidentifier ::= sequence { // keyidentifier [0] keyidentifier optional, // authoritycertissuer [1] generalnames optional, // authoritycertserialnumber [2] certificateserialnumber optional } // -- authoritycertissuer and authoritycertserialnumber must both // -- be present or both be absent type authkeyid struct { keyidentifier []byte `asn1:"optional,tag:0"` authoritycertissuer generalnames `asn1:"optional,tag:1"` authoritycertserialnumber *big.int `asn1:"optional,tag:2"` } // rfc 5280, a.2. implicitly tagged module, 1988 syntax // // generalnames ::= sequence size (1..max) of generalname // // generalname ::= choice { // othername [0] anothername, // rfc822name [1] ia5string, // dnsname [2] ia5string, // x400address [3] oraddress, // directoryname [4] name, // edipartyname [5] edipartyname, // uniformresourceidentifier [6] ia5string, // ipaddress [7] octet string, // registeredid [8] object identifier } type generalnames struct { name []pkix.rdnsequence `asn1:"tag:4"` } func gen(issuer *x509.certificate) ([]byte, error) { return asn1.marshal(authkeyid{ keyidentifier: issuer.subjectkeyid, authoritycertissuer: generalnames{name: []pkix.rdnsequence{issuer.issuer.tordnsequence()}}, authoritycertserialnumber: issuer.serialnumber, }) } func main() { cacert := `-----begin certificate----- miibotccauegawibagiqgocjdjn1y6rgwebxw8v8mdakbggqhkjopqqdajammq8w dqydvqqkewznesbpcmcxezarbgnvbamtck15ifjvb3qgq0ewhhcnmjmwnte2mtqy ntuwwhcnmjmwnte3mtuyntuwwjammq8wdqydvqqkewznesbpcmcxezarbgnvbamt ck15ifjvb3qgq0ewwtatbgcqhkjopqibbggqhkjopqmbbwncaarzqz2ka7fi6w9/ 32sjhtajrke+vqyx7hfnmtx1inpbajnfvonf2silh5nqms50jpnvgivehtbfl0a0 dcurufhno1cwvtaobgnvhq8baf8ebamcaqqwewydvr0lbawwcgyikwybbquhawew dwydvr0taqh/bauwaweb/zadbgnvhq4efgqu5y48dj96lqwvh3s/anj/6sgy/j4w cgyikozizj0eawidsaawrqihanqdh6sgz014wvfdh0zhbeghdb2tqxzujxa7ymo3 80unaiapzp4wlzqlb+j4fipnep+txru01jgfaksml2yhv3mewg== -----end certificate-----` b, _ := pem.decode([]byte(cacert)) if b == nil { panic("couldn't decode test certificate") } issuer, err := x509.parsecertificate(b.bytes) if err != nil { panic(err) } authoritykeyidentifiervalue, err := gen(issuer) if err != nil { panic(err) } fmt.println(hex.encodetostring(authoritykeyidentifiervalue)) }
La valeur de codage hexadécimal est :
30548014e58e3c0c9f7a2d05958774bf68d27fe921b2fe3ea12aa4283026310f300d060355040a13064d79204f7267311330110603550403130a4d7920526f6f7420434182101a80a30c937563aac65846d75bc57c30
Les chaînes hexadécimales peuvent être créées à l'aide d'un décodeur javascript tel que asn.1 :
La démo c# suivante donne le même résultat :
using system.security.cryptography.x509certificates; using system.text; internal class program { private static void main(string[] args) { var certbytes = encoding.ascii.getbytes(@"-----begin certificate----- miibotccauegawibagiqgocjdjn1y6rgwebxw8v8mdakbggqhkjopqqdajammq8w dqydvqqkewznesbpcmcxezarbgnvbamtck15ifjvb3qgq0ewhhcnmjmwnte2mtqy ntuwwhcnmjmwnte3mtuyntuwwjammq8wdqydvqqkewznesbpcmcxezarbgnvbamt ck15ifjvb3qgq0ewwtatbgcqhkjopqibbggqhkjopqmbbwncaarzqz2ka7fi6w9/ 32sjhtajrke+vqyx7hfnmtx1inpbajnfvonf2silh5nqms50jpnvgivehtbfl0a0 dcurufhno1cwvtaobgnvhq8baf8ebamcaqqwewydvr0lbawwcgyikwybbquhawew dwydvr0taqh/bauwaweb/zadbgnvhq4efgqu5y48dj96lqwvh3s/anj/6sgy/j4w cgyikozizj0eawidsaawrqihanqdh6sgz014wvfdh0zhbeghdb2tqxzujxa7ymo3 80unaiapzp4wlzqlb+j4fipnep+txru01jgfaksml2yhv3mewg== -----end certificate-----"); using var issuer = new x509certificate2(certbytes); var e = x509authoritykeyidentifierextension.createfromcertificate(issuer, true, true); console.writeline(bytearraytohex(e.rawdata)); } private static string bytearraytohex(byte[] bytes) { var builder = new stringbuilder(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { builder.append($"{bytes[i]:x2}"); } return builder.tostring(); } }
Mise à jour :
Il s'agit d'une version mise à jour de gen
qui inclut l'adresse e-mail :
func gen(issuer *x509.Certificate) ([]byte, error) { rdnSequence := issuer.Issuer.ToRDNSequence() if len(issuer.EmailAddresses) > 0 { oidEmail := asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1} emails := make([]pkix.AttributeTypeAndValue, len(issuer.EmailAddresses)) for i, value := range issuer.EmailAddresses { emails[i].Type = oidEmail emails[i].Value = value } rdnSequence = append(rdnSequence, emails) } return asn1.Marshal(authKeyId{ KeyIdentifier: issuer.SubjectKeyId, AuthorityCertIssuer: generalNames{Name: []pkix.RDNSequence{rdnSequence}}, AuthorityCertSerialNumber: issuer.SerialNumber, }) }
Veuillez noter qu'oid est obsolète (voir http://oid-info.com/get/1.2.840.113549.1.9.1). .net ne l'inclut pas non plus.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!