Skip to content

Commit

Permalink
cfca: add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
emmansun authored Jan 23, 2025
1 parent ee55d37 commit 9e57bb9
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 4 deletions.
180 changes: 180 additions & 0 deletions cfca/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package cfca_test

import (
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"fmt"

"github.com/emmansun/gmsm/cfca"
"github.com/emmansun/gmsm/sm2"
)

func ExampleParseSM2() {
base64data := `
MIIDSQIBATBHBgoqgRzPVQYBBAIBBgcqgRzPVQFoBDDkLvKllj9ZWhaKU6MSnxBBV5yaF3tEcOk1
vQniWyVzyaQA4F3j/YvDJwEoE8gOF/swggL5BgoqgRzPVQYBBAIBBIIC6TCCAuUwggKJoAMCAQIC
BRBAmQgJMAwGCCqBHM9VAYN1BQAwXDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFu
Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEbMBkGA1UEAwwSQ0ZDQSBURVNUIFNNMiBPQ0Ex
MB4XDTIwMTExOTA4MzExOFoXDTI1MTExOTA4MzExOFowgYkxCzAJBgNVBAYTAkNOMRcwFQYDVQQK
DA5DRkNBIFRFU1QgT0NBMTENMAsGA1UECwwEUFNCQzEZMBcGA1UECwwQT3JnYW5pemF0aW9uYWwt
MjE3MDUGA1UEAwwuMDUxQOmCruWCqOe6v+S4iuaUtuWNleWVhuaIt0BONTEwMTEzMDAwMTg4NzhA
MTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABJVRC63OKfcL4H324rDOdb4SSlbAjoJDXnK0qmwX
Z59FWmiSqt3ipreljKew4QynjTgR/yfp9yjNgNU8G5pkYdujggEGMIIBAjAfBgNVHSMEGDAWgBRr
/hjaj0I6prhtsy6Igzo0osEw4TAMBgNVHRMBAf8EAjAAMEgGA1UdIARBMD8wPQYIYIEchu8qAQEw
MTAvBggrBgEFBQcCARYjaHR0cDovL3d3dy5jZmNhLmNvbS5jbi91cy91cy0xNC5odG0wOQYDVR0f
BDIwMDAuoCygKoYoaHR0cDovL3VjcmwuY2ZjYS5jb20uY24vU00yL2NybDE0MzU2LmNybDAOBgNV
HQ8BAf8EBAMCBsAwHQYDVR0OBBYEFPiGPZT0oTuRXvkyGoOgviNEWnc1MB0GA1UdJQQWMBQGCCsG
AQUFBwMCBggrBgEFBQcDBDAMBggqgRzPVQGDdQUAA0gAMEUCIQCJDSsVPfhr+gnDASMj5Syt+hxs
amHygPecjCLbcdFQQgIgSXC4musF5Fnj/CpNTqvk9+56FuINkATGS8xRh7kzKBE=`
password := []byte("123456")
data, err := base64.StdEncoding.DecodeString(base64data)
if err != nil {
panic(err)
}
priv, cert, err := cfca.ParseSM2(password, data)
if err != nil {
panic(err)
}
fmt.Printf("%x\n", priv.D.Bytes())
fmt.Printf("%v\n", cert.Issuer)
// Output: d3f24d61bb2816882b8474b778dd7c3166d665f9455dc9d551c989c161e76ab0
// CN=CFCA TEST SM2 OCA1,O=China Financial Certification Authority,C=CN
}

func ExampleParseSM2_pemEncoded() {
pemdata := `
-----BEGIN CFCA KEY-----
MIIDSQIBATBHBgoqgRzPVQYBBAIBBgcqgRzPVQFoBDDkLvKllj9ZWhaKU6MSnxBBV5yaF3tEcOk1
vQniWyVzyaQA4F3j/YvDJwEoE8gOF/swggL5BgoqgRzPVQYBBAIBBIIC6TCCAuUwggKJoAMCAQIC
BRBAmQgJMAwGCCqBHM9VAYN1BQAwXDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFu
Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEbMBkGA1UEAwwSQ0ZDQSBURVNUIFNNMiBPQ0Ex
MB4XDTIwMTExOTA4MzExOFoXDTI1MTExOTA4MzExOFowgYkxCzAJBgNVBAYTAkNOMRcwFQYDVQQK
DA5DRkNBIFRFU1QgT0NBMTENMAsGA1UECwwEUFNCQzEZMBcGA1UECwwQT3JnYW5pemF0aW9uYWwt
MjE3MDUGA1UEAwwuMDUxQOmCruWCqOe6v+S4iuaUtuWNleWVhuaIt0BONTEwMTEzMDAwMTg4NzhA
MTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABJVRC63OKfcL4H324rDOdb4SSlbAjoJDXnK0qmwX
Z59FWmiSqt3ipreljKew4QynjTgR/yfp9yjNgNU8G5pkYdujggEGMIIBAjAfBgNVHSMEGDAWgBRr
/hjaj0I6prhtsy6Igzo0osEw4TAMBgNVHRMBAf8EAjAAMEgGA1UdIARBMD8wPQYIYIEchu8qAQEw
MTAvBggrBgEFBQcCARYjaHR0cDovL3d3dy5jZmNhLmNvbS5jbi91cy91cy0xNC5odG0wOQYDVR0f
BDIwMDAuoCygKoYoaHR0cDovL3VjcmwuY2ZjYS5jb20uY24vU00yL2NybDE0MzU2LmNybDAOBgNV
HQ8BAf8EBAMCBsAwHQYDVR0OBBYEFPiGPZT0oTuRXvkyGoOgviNEWnc1MB0GA1UdJQQWMBQGCCsG
AQUFBwMCBggrBgEFBQcDBDAMBggqgRzPVQGDdQUAA0gAMEUCIQCJDSsVPfhr+gnDASMj5Syt+hxs
amHygPecjCLbcdFQQgIgSXC4musF5Fnj/CpNTqvk9+56FuINkATGS8xRh7kzKBE=
-----END CFCA KEY-----`
password := []byte("123456")
block, _ := pem.Decode([]byte(pemdata))
if block == nil {
panic("failed to decode PEM block")
}
priv, cert, err := cfca.ParseSM2(password, block.Bytes)
if err != nil {
panic(err)
}
fmt.Printf("%x\n", priv.D.Bytes())
fmt.Printf("%v\n", cert.Issuer)
// Output: d3f24d61bb2816882b8474b778dd7c3166d665f9455dc9d551c989c161e76ab0
// CN=CFCA TEST SM2 OCA1,O=China Financial Certification Authority,C=CN
}

func ExampleMarshalSM2_changePassword() {
pemdata := `
-----BEGIN CFCA KEY-----
MIIDSQIBATBHBgoqgRzPVQYBBAIBBgcqgRzPVQFoBDDkLvKllj9ZWhaKU6MSnxBBV5yaF3tEcOk1
vQniWyVzyaQA4F3j/YvDJwEoE8gOF/swggL5BgoqgRzPVQYBBAIBBIIC6TCCAuUwggKJoAMCAQIC
BRBAmQgJMAwGCCqBHM9VAYN1BQAwXDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFu
Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEbMBkGA1UEAwwSQ0ZDQSBURVNUIFNNMiBPQ0Ex
MB4XDTIwMTExOTA4MzExOFoXDTI1MTExOTA4MzExOFowgYkxCzAJBgNVBAYTAkNOMRcwFQYDVQQK
DA5DRkNBIFRFU1QgT0NBMTENMAsGA1UECwwEUFNCQzEZMBcGA1UECwwQT3JnYW5pemF0aW9uYWwt
MjE3MDUGA1UEAwwuMDUxQOmCruWCqOe6v+S4iuaUtuWNleWVhuaIt0BONTEwMTEzMDAwMTg4NzhA
MTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABJVRC63OKfcL4H324rDOdb4SSlbAjoJDXnK0qmwX
Z59FWmiSqt3ipreljKew4QynjTgR/yfp9yjNgNU8G5pkYdujggEGMIIBAjAfBgNVHSMEGDAWgBRr
/hjaj0I6prhtsy6Igzo0osEw4TAMBgNVHRMBAf8EAjAAMEgGA1UdIARBMD8wPQYIYIEchu8qAQEw
MTAvBggrBgEFBQcCARYjaHR0cDovL3d3dy5jZmNhLmNvbS5jbi91cy91cy0xNC5odG0wOQYDVR0f
BDIwMDAuoCygKoYoaHR0cDovL3VjcmwuY2ZjYS5jb20uY24vU00yL2NybDE0MzU2LmNybDAOBgNV
HQ8BAf8EBAMCBsAwHQYDVR0OBBYEFPiGPZT0oTuRXvkyGoOgviNEWnc1MB0GA1UdJQQWMBQGCCsG
AQUFBwMCBggrBgEFBQcDBDAMBggqgRzPVQGDdQUAA0gAMEUCIQCJDSsVPfhr+gnDASMj5Syt+hxs
amHygPecjCLbcdFQQgIgSXC4musF5Fnj/CpNTqvk9+56FuINkATGS8xRh7kzKBE=
-----END CFCA KEY-----`
password := []byte("123456")
block, _ := pem.Decode([]byte(pemdata))
if block == nil {
panic("failed to decode PEM block")
}
priv, cert, err := cfca.ParseSM2(password, block.Bytes)
if err != nil {
panic(err)
}
newpassword := []byte("654321")
data, err := cfca.MarshalSM2(newpassword, priv, cert)
if err != nil {
panic(err)
}
priv2, cert2, err := cfca.ParseSM2(newpassword, data)
if err != nil {
panic(err)
}
fmt.Printf("%x\n", priv2.D.Bytes())
fmt.Printf("%v\n", cert2.Issuer)
// Output: d3f24d61bb2816882b8474b778dd7c3166d665f9455dc9d551c989c161e76ab0
// CN=CFCA TEST SM2 OCA1,O=China Financial Certification Authority,C=CN
}

func ExampleCreateCertificateRequest() {
keyBytes, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85")
priv, err := sm2.NewPrivateKey(keyBytes)
if err != nil {
panic(err)
}
random := rand.Reader

// tmpKey used to decrypt the returned escrow PrivateKey
keyBytes, _ = hex.DecodeString("cacece36cac24aab94e52bcd5c0f552c95028f2856053135a1e47510b4c307ba")
tmpKey, err := sm2.NewPrivateKey(keyBytes)
if err != nil {
panic(err)
}
template := &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "certRequisition",
Organization: []string{"CFCA TEST CA"},
Country: []string{"CN"},
},
}
csrder, err := cfca.CreateCertificateRequest(random, template, priv, &tmpKey.PublicKey, "123456")
if err != nil {
panic(err)
}
// you can encode the csrder to PEM format or base64 format

csr, err := cfca.ParseCertificateRequest(csrder)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", csr.Subject)
fmt.Printf("%v\n", csr.ChallengePassword)
fmt.Printf("%x\n", csr.TmpPublicKey.(*ecdsa.PublicKey).X)
// Output: CN=certRequisition,O=CFCA TEST CA,C=CN
// 123456
// c7c4d0945ebdfc2111ad64b0e92e04582b0725fea172968c6c40162c810f8882
}

func ExampleParseEscrowPrivateKey() {
// a sample method to parse the escrow private key
keydata := `00000000000000010000000000000001000000000000000000000000000000000000000000000268MIHGAgEBBIHArhtKwTVT8dPEkykVRpvQNMxHv/yeqtaKZiSp2MbjcqMZtPfKW8IatiIPPitNhQtU5C7gMbsUxgf5Yo16vDSXdoWqoOOaes2pEJwmXWZI55lMMWc168WgzQ82fmMi05Vhlw9HNjGI3azE6MS5/ujSNGLZ0qAAmLnBiHlXFAXXAWRiy9MxZKwF4xKn6qMaKmkqbYmTbBbEJEhzJBmu0IJ1kNDcTFirAyapghHSw267erSUwsHjkQis9mKYpzGied0E`
keyBytes, _ := hex.DecodeString("cacece36cac24aab94e52bcd5c0f552c95028f2856053135a1e47510b4c307ba")
tmpKey, err := sm2.NewPrivateKey(keyBytes)
if err != nil {
panic(err)
}

encKey, err := cfca.ParseEscrowPrivateKey(tmpKey, []byte(keydata))
if err != nil {
panic(err)
}
fmt.Printf("%x\n", encKey.D.Bytes())
// Output: f6e02c941a0dfdac58d8b3b1bc1bd136f179741b7465ebc7b0b25bb381840a3b
}
2 changes: 1 addition & 1 deletion cfca/pkcs12_sm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func ParseSM2(password, data []byte) (*sm2.PrivateKey, *smx509.Certificate, erro
}
pk, err := DecryptBySM4CBC(keys.EncryptedKey.EncryptedContent.Bytes, password)
if err != nil {
return nil, nil, err
return nil, nil, fmt.Errorf("cfca: failed to decrypt by SM4-CBC, please ensure the password is correct")
}
prvKey, err := sm2.NewPrivateKeyFromInt(new(big.Int).SetBytes(pk))
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cfca/pkcs12_sm2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ func TestParseSM2WithInvalidPwd(t *testing.T) {
password := []byte("wrongpwd")
der, _ := hex.DecodeString("308203490201013047060a2a811ccf55060104020106072a811ccf5501680430016ca58c339f32f5bbe2b0491d5087c9b5de0f5aef4b4d0726941a0c21d9795f51e802f2a1596cc909d1638067ca28cc308202f9060a2a811ccf550601040201048202e9308202e530820289a00302010202051040990809300c06082a811ccf550183750500305c310b300906035504061302434e3130302e060355040a0c274368696e612046696e616e6369616c2043657274696669636174696f6e20417574686f72697479311b301906035504030c1243464341205445535420534d32204f434131301e170d3230313131393038333131385a170d3235313131393038333131385a308189310b300906035504061302434e31173015060355040a0c0e434643412054455354204f434131310d300b060355040b0c045053424331193017060355040b0c104f7267616e697a6174696f6e616c2d323137303506035504030c2e30353140e982aee582a8e7babfe4b88ae694b6e58d95e59586e688b7404e353130313133303030313838373840313059301306072a8648ce3d020106082a811ccf5501822d0342000495510badce29f70be07df6e2b0ce75be124a56c08e82435e72b4aa6c17679f455a6892aadde2a6b7a58ca7b0e10ca78d3811ff27e9f728cd80d53c1b9a6461dba382010630820102301f0603551d230418301680146bfe18da8f423aa6b86db32e88833a34a2c130e1300c0603551d130101ff0402300030480603551d200441303f303d060860811c86ef2a01013031302f06082b060105050702011623687474703a2f2f7777772e636663612e636f6d2e636e2f75732f75732d31342e68746d30390603551d1f04323030302ea02ca02a8628687474703a2f2f7563726c2e636663612e636f6d2e636e2f534d322f63726c31343335362e63726c300e0603551d0f0101ff0404030206c0301d0603551d0e04160414f8863d94f4a13b915ef9321a83a0be23445a7735301d0603551d250416301406082b0601050507030206082b06010505070304300c06082a811ccf5501837505000348003045022100890d2b153df86bfa09c3012323e52cadfa1c6c6a61f280f79c8c22db71d1504202204970b89aeb05e459e3fc2a4d4eabe4f7ee7a16e20d9004c64bcc5187b9332811")
_, _, err := ParseSM2(password, der)
if err == nil || err.Error() != "padding: invalid padding byte/length" {
t.Fatal("expected error of padding: invalid padding byte/length")
if err == nil || err.Error() != "cfca: failed to decrypt by SM4-CBC, please ensure the password is correct" {
t.Fatal("cfca: failed to decrypt by SM4-CBC, please ensure the password is correct")
}
}

Expand Down
2 changes: 1 addition & 1 deletion docs/cfca.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@ SADK 3.2之后的版本,支持下列SM2密文格式(encryptedType):
使用`cfca.ParseEscrowPrivateKey`解析CFCA返回的加密用私钥。

### SM2私钥、证书的解析
这个是CFCA自定义的,未见相关标准,可以通过```cfca.ParseSM2```来解析。
这个是CFCA自定义的,未见相关标准,可以通过```cfca.ParseSM2```来解析。```cfca.ParseSM2```函数只接受**DER**编码的二进制数据,如果你的数据是**base64**编码的,请先自行解码。

0 comments on commit 9e57bb9

Please sign in to comment.