pkcs12

Public Key Infrastructure (PKI) provides the means to establish trust by binding public keys and identities, thus giving reasonable assurance that we’re communicating securely with who we think we are. PKI is important to using public key cryptography effectively, and is essential to understanding and using the SSL protocol.

Using public key cryptography, we can be sure that only the encrypted data can be decrypted with the corresponding private key. If we combine this with the use of a message digest algorithm to compute a signature, we can be sure that the encrypted data has not been tampered with. What’s missing is some means of ensuring that the party we’re communicating with is actually who they say they are. In other words, trust has not been established. This is where PKI fits in.

 

https://www.golinuxcloud.com/tutorial-pki-certificates-authority-ocsp/#:~:text=PFX%2FP12%20The%20Personal%20Information%20Exchange%20%28PFX%29%20format%2C%20also,PFX%20formatted%20files%20have%20an%20extension%20of.pfx%20or.p12.

 

Certificate Formats

There are different certificate formats because of the way the information is stored in the certificate. The following identifies common file formats for certificates:

  • DER/CER   Distinguished Encoding Rules (DER) and Canonical Encoding Rules (CER) are binary file formats used to store information in the certificate file. DER-formatted files can have a .der or a .cer file extension.
  • PEM   Privacy-enhanced Electronic Mail (PEM) is an ASCII file format that can have a file extension of .pem.crt.cer, or .key. PEM files are very common and start with -----BEGIN CERTIFICATE----- and end with -----END CERTIFICATE-----.
  • PFX/P12   The Personal Information Exchange (PFX) format, also known as the P12 or PKCS#12 format, is a binary file format that is common with Microsoft environments for importing and exporting certificates. PFX formatted files have an extension of .pfx or .p12.
  • P7B   The P7B format, also known as PKCS#7, is another ASCII file format used to store certificate information. If you open the ASCII file, you will see that it begins with the text -----BEGIN PKCS7----- and ends with -----END PKCS7-----. P7B files can have an extension of .p7b or .p7c.

 

 

Certificate Revocation Lists

Once a certificate has been issued, it is generally put into production, where it will be distributed to many clients. If an attacker compromises the associated private key, he now has the ability to use the certificate even though it doesn’t belong to him. Assuming the proper owner is aware of the compromise, a new certificate with a new key pair should be obtained and put into use. In this situation there are two certificates for the same entity—both are technically valid, but one should not be trusted. The compromised certificate will eventually expire, but in the meantime, how will the world at large know not to trust it?

The answer lies in something called a certificate revocation list (CRL). A CRL contains a list of all of the revoked certificates a CA has issued that have yet to expire. When a certificate is revoked, the CA declares that the certificate should no longer be trusted.

 

Online Certificate Status Protocol

The Online Certificate Status Protocol (OCSP), formally specified in RFC 2560, is a relatively new addition to PKI. Its primary aim is to address some of the distribution problems that have traditionally plagued CRLs.

Using OCSP, an application makes a connection to an OCSP responder and requests the status of a certificate by passing the certificate’s serial number. The responder replies “good,” “revoked,” or “unknown.” A “good” response indicates that the certificate is valid, so far as the responder knows. This does not necessarily mean that the certificate was ever issued, just that is hasn’t been revoked. A “revoked” response indicates that the certificate has been issued and that it has indeed been revoked. An “unknown” response indicates that the responder doesn’t know anything about the certificate. A typical reason for this response could be that the certificate was issued by a CA that is unknown to the responder.

 

 

"golang.org/x/crypto/pkcs12"

 

func main() {
clientStore := "/Users/jalyzhang/Documents/test/src/github.com/ultramesh/flato-msp-cert/z/client.keystore";
clientpwd := "client";
data, _ := ioutil.ReadFile(clientStore)
priv, cert, err := pkcs12.Decode(data, clientpwd)
if (err != nil){
panic(err)
}
fmt.Println(priv)
fmt.Println(cert)
}

 

 

//add encode

// Encode produces pfxData containing one private key, an end-entity certificate, and any number of CA certificates.
// It emulates the behavior of OpenSSL's PKCS12_create: it creates two SafeContents: one that's encrypted with RC2
// and contains the certificates, and another that is unencrypted and contains the private key shrouded with 3DES.
// The private key bag and the end-entity certificate bag have the LocalKeyId attribute set to the SHA-1 fingerprint
// of the end-entity certificate.
func Encode(privateKey interface{}, certificate *sm2.Certificate, caCerts []*x509.Certificate, password string) (pfxData []byte, err error) {
encodedPassword, err := bmpString(password)
if err != nil {
return nil, err
}

var pfx pfxPdu
pfx.Version = 3

var certFingerprint = sha1.Sum(certificate.Raw)
var localKeyIdAttr pkcs12Attribute
localKeyIdAttr.Id = oidLocalKeyID
localKeyIdAttr.Value.Class = 0
localKeyIdAttr.Value.Tag = 17
localKeyIdAttr.Value.IsCompound = true
if localKeyIdAttr.Value.Bytes, err = asn1.Marshal(certFingerprint[:]); err != nil {
return nil, err
}

var certBags []safeBag
var certBag *safeBag
if certBag, err = makeCertBag(certificate.Raw, []pkcs12Attribute{localKeyIdAttr}); err != nil {
return nil, err
}
certBags = append(certBags, *certBag)

for _, cert := range caCerts {
if certBag, err = makeCertBag(cert.Raw, []pkcs12Attribute{}); err != nil {
return nil, err
}
certBags = append(certBags, *certBag)
}

var keyBag safeBag
keyBag.Id = oidPKCS8ShroundedKeyBag
keyBag.Value.Class = 2
keyBag.Value.Tag = 0
keyBag.Value.IsCompound = true
if keyBag.Value.Bytes, err = encodePkcs8ShroudedKeyBag(privateKey, encodedPassword); err != nil {
return nil, err
}
keyBag.Attributes = append(keyBag.Attributes, localKeyIdAttr)

// Construct an authenticated safe with two SafeContents.
// The first SafeContents is encrypted and contains the cert bags.
// The second SafeContents is unencrypted and contains the shrouded key bag.
var authenticatedSafe [2]contentInfo
if authenticatedSafe[0], err = makeSafeContents(certBags, encodedPassword); err != nil {
return nil, err
}
if authenticatedSafe[1], err = makeSafeContents([]safeBag{keyBag}, nil); err != nil {
return nil, err
}

var authenticatedSafeBytes []byte
if authenticatedSafeBytes, err = asn1.Marshal(authenticatedSafe[:]); err != nil {
return nil, err
}

// compute the MAC
pfx.MacData.Mac.Algorithm.Algorithm = oidSHA1
pfx.MacData.MacSalt = make([]byte, 8)
if _, err = rand.Read(pfx.MacData.MacSalt); err != nil {
return nil, err
}
pfx.MacData.Iterations = 1
if err = computeMac(&pfx.MacData, authenticatedSafeBytes, encodedPassword); err != nil {
return nil, err
}

pfx.AuthSafe.ContentType = oidDataContentType
pfx.AuthSafe.Content.Class = 2
pfx.AuthSafe.Content.Tag = 0
pfx.AuthSafe.Content.IsCompound = true
if pfx.AuthSafe.Content.Bytes, err = asn1.Marshal(authenticatedSafeBytes); err != nil {
return nil, err
}

if pfxData, err = asn1.Marshal(pfx); err != nil {
return nil, errors.New("go-pkcs12: error writing P12 data: " + err.Error())
}
return
}

func makeCertBag(certBytes []byte, attributes []pkcs12Attribute) (certBag *safeBag, err error) {
certBag = new(safeBag)
certBag.Id = oidCertBag
certBag.Value.Class = 2
certBag.Value.Tag = 0
certBag.Value.IsCompound = true
if certBag.Value.Bytes, err = encodeCertBag(certBytes); err != nil {
return nil, err
}
certBag.Attributes = attributes
return
}

func makeSafeContents(bags []safeBag, password []byte) (ci contentInfo, err error) {
var data []byte
if data, err = asn1.Marshal(bags); err != nil {
return
}

if password == nil {
ci.ContentType = oidDataContentType
ci.Content.Class = 2
ci.Content.Tag = 0
ci.Content.IsCompound = true
if ci.Content.Bytes, err = asn1.Marshal(data); err != nil {
return
}
} else {
randomSalt := make([]byte, 8)
if _, err = rand.Read(randomSalt); err != nil {
return
}

var algo pkix.AlgorithmIdentifier
algo.Algorithm = oidPBEWithSHAAnd40BitRC2CBC
if algo.Parameters.FullBytes, err = asn1.Marshal(pbeParams{Salt: randomSalt, Iterations: 2048}); err != nil {
return
}

var encryptedData encryptedData
encryptedData.Version = 0
encryptedData.EncryptedContentInfo.ContentType = oidDataContentType
encryptedData.EncryptedContentInfo.ContentEncryptionAlgorithm = algo
if err = pbEncrypt(&encryptedData.EncryptedContentInfo, data, password); err != nil {
return
}

ci.ContentType = oidEncryptedDataContentType
ci.Content.Class = 2
ci.Content.Tag = 0
ci.Content.IsCompound = true
if ci.Content.Bytes, err = asn1.Marshal(encryptedData); err != nil {
return
}
}
return
}
func SM2P12Encrypt(certificate *sm2.Certificate, pwd string, priv *sm2.PrivateKey, fileName string) error {
pfxDataNew, err := Encode(priv, certificate, nil, pwd)
if err != nil {
return err
}
err = ioutil.WriteFile(fileName, pfxDataNew, 0666)
return err
}
func SM2P12Decrypt(fileName string, pwd string) (*sm2.Certificate, *sm2.PrivateKey, error) {
pfxData, _ := ioutil.ReadFile(fileName)
pv, cer, err := DecodeAll(pfxData, pwd)
if err != nil {
return nil, nil, err
}
switch k := pv.(type) {
case *ecdsa.PrivateKey:
switch k.Curve {
case sm2.P256Sm2():
sm2pub := &sm2.PublicKey{
Curve: k.Curve,
X: k.X,
Y: k.Y,
}
sm2Pri := &sm2.PrivateKey{
PublicKey: *sm2pub,
D: k.D,
}
if !k.IsOnCurve(k.X,k.Y) {
return nil, nil, errors.New("error while validating SM2 private key: %v")
}
return cer[0], sm2Pri, nil
}
default:
return nil, nil, errors.New("unexpected type for p12 private key")
}
return nil,nil,nil
}

 

 

 

type pfxPdu struct {
Version int
AuthSafe contentInfo
MacData macData `asn1:"optional"`
}

type contentInfo struct {
ContentType asn1.ObjectIdentifier
Content asn1.RawValue `asn1:"tag:0,explicit,optional"`
}


type macData struct {
Mac digestInfo
MacSalt []byte
Iterations int `asn1:"optional,default:1"`
}

type digestInfo struct {
Algorithm pkix.AlgorithmIdentifier
Digest []byte
}

 


type contentInfo struct {
ContentType asn1.ObjectIdentifier
Content asn1.RawValue `asn1:"tag:0,explicit,optional"`
}

type encryptedData struct {
Version int
EncryptedContentInfo encryptedContentInfo
}

type encryptedContentInfo struct {
ContentType asn1.ObjectIdentifier
ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
EncryptedContent []byte `asn1:"tag:0,optional"`
}

 

type safeBag struct {
Id asn1.ObjectIdentifier
Value asn1.RawValue `asn1:"tag:0,explicit"`
Attributes []pkcs12Attribute `asn1:"set,optional"`
}

type pkcs12Attribute struct {
Id asn1.ObjectIdentifier
Value asn1.RawValue `asn1:"set"`
}


type certBag struct {
Id asn1.ObjectIdentifier
Data []byte `asn1:"tag:0,explicit"`
}

 

type encryptedPrivateKeyInfo struct {
AlgorithmIdentifier pkix.AlgorithmIdentifier
EncryptedData []byte
}

 

posted @ 2020-11-09 15:16  zJanly  阅读(448)  评论(0编辑  收藏  举报