diff --git a/.gitignore b/.gitignore index b08a64c..d27d7ce 100644 --- a/.gitignore +++ b/.gitignore @@ -66,7 +66,6 @@ __debug_bin # 临时文件 # ###################### -go.sum tmp/ .tmp/ diff --git a/cryptobin/ca/ca_test.go b/cryptobin/ca/ca_test.go index bb168aa..27259c8 100644 --- a/cryptobin/ca/ca_test.go +++ b/cryptobin/ca/ca_test.go @@ -58,6 +58,34 @@ func Test_GenerateKey(t *testing.T) { assertError(obj.Error(), "Test_GenerateKey") assertNotEmpty(prikey, "Test_GenerateKey-prikey") assertNotEmpty(pubkey, "Test_GenerateKey-pubkey") + + pass := []byte("12345678") + prikey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + pubkey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + + assertNotEmpty(prikey2, "Test_GenerateKey-prikey2") + assertNotEmpty(pubkey2, "Test_GenerateKey-pubkey2") + }) + + t.Run("GenerateDSAKey", func(t *testing.T) { + obj := New(). + SetPublicKeyType("DSA"). + SetParameterSizes("L1024N160"). + GenerateKey() + + prikey := obj.CreatePrivateKey().ToKeyString() + pubkey := obj.CreatePublicKey().ToKeyString() + + assertError(obj.Error(), "Test_GenerateKey") + assertNotEmpty(prikey, "Test_GenerateKey-prikey") + assertNotEmpty(pubkey, "Test_GenerateKey-pubkey") + + pass := []byte("12345678") + prikey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + pubkey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + + assertNotEmpty(prikey2, "Test_GenerateKey-prikey2") + assertNotEmpty(pubkey2, "Test_GenerateKey-pubkey2") }) t.Run("GenerateECDSAKey", func(t *testing.T) { @@ -72,6 +100,13 @@ func Test_GenerateKey(t *testing.T) { assertError(obj.Error(), "Test_GenerateKey") assertNotEmpty(prikey, "Test_GenerateKey-prikey") assertNotEmpty(pubkey, "Test_GenerateKey-pubkey") + + pass := []byte("12345678") + prikey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + pubkey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + + assertNotEmpty(prikey2, "Test_GenerateKey-prikey2") + assertNotEmpty(pubkey2, "Test_GenerateKey-pubkey2") }) t.Run("GenerateEdDSAKey", func(t *testing.T) { @@ -85,6 +120,13 @@ func Test_GenerateKey(t *testing.T) { assertError(obj.Error(), "Test_GenerateKey") assertNotEmpty(prikey, "Test_GenerateKey-prikey") assertNotEmpty(pubkey, "Test_GenerateKey-pubkey") + + pass := []byte("12345678") + prikey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + pubkey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + + assertNotEmpty(prikey2, "Test_GenerateKey-prikey2") + assertNotEmpty(pubkey2, "Test_GenerateKey-pubkey2") }) t.Run("GenerateSM2Key", func(t *testing.T) { @@ -98,6 +140,13 @@ func Test_GenerateKey(t *testing.T) { assertError(obj.Error(), "Test_GenerateKey") assertNotEmpty(prikey, "Test_GenerateKey-prikey") assertNotEmpty(pubkey, "Test_GenerateKey-pubkey") + + pass := []byte("12345678") + prikey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + pubkey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + + assertNotEmpty(prikey2, "Test_GenerateKey-prikey2") + assertNotEmpty(pubkey2, "Test_GenerateKey-pubkey2") }) t.Run("GenerateRSAKey 2", func(t *testing.T) { @@ -112,6 +161,13 @@ func Test_GenerateKey(t *testing.T) { assertError(obj.Error(), "Test_GenerateKey") assertNotEmpty(prikey, "Test_GenerateKey-prikey") assertNotEmpty(pubkey, "Test_GenerateKey-pubkey") + + pass := []byte("12345678") + prikey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + pubkey2 := obj.CreatePrivateKeyWithPassword(pass).ToKeyString() + + assertNotEmpty(prikey2, "Test_GenerateKey-prikey2") + assertNotEmpty(pubkey2, "Test_GenerateKey-pubkey2") }) } @@ -132,6 +188,17 @@ func Test_GenerateKey2(t *testing.T) { assertNotEmpty(pubkey, "Test_GenerateKey2-pubkey") }) + t.Run("GenerateDSAKey", func(t *testing.T) { + obj := New().GenerateDSAKey("L2048N224") + + prikey := obj.CreatePrivateKey().ToKeyString() + pubkey := obj.CreatePublicKey().ToKeyString() + + assertError(obj.Error(), "Test_GenerateKey2") + assertNotEmpty(prikey, "Test_GenerateKey2-prikey") + assertNotEmpty(pubkey, "Test_GenerateKey2-pubkey") + }) + t.Run("GenerateECDSAKey", func(t *testing.T) { obj := New(). GenerateECDSAKey("P256") diff --git a/cryptobin/ca/create.go b/cryptobin/ca/create.go index 0a2b269..66f79d6 100644 --- a/cryptobin/ca/create.go +++ b/cryptobin/ca/create.go @@ -11,12 +11,29 @@ import ( "crypto/x509" "encoding/pem" + "github.com/deatil/go-cryptobin/pkcs8" "github.com/deatil/go-cryptobin/pkcs12" "github.com/deatil/go-cryptobin/gm/sm2" cryptobin_x509 "github.com/deatil/go-cryptobin/x509" pubkey_dsa "github.com/deatil/go-cryptobin/pubkey/dsa" ) +type ( + // options + Opts = pkcs8.Opts + // PBKDF2 options + PBKDF2Opts = pkcs8.PBKDF2Opts + // Scrypt options + ScryptOpts = pkcs8.ScryptOpts +) + +var ( + // get Cipher type + GetCipherFromName = pkcs8.GetCipherFromName + // get hash type + GetHashFromName = pkcs8.GetHashFromName +) + // CA 证书 func (this CA) CreateCA() CA { if this.publicKey == nil || this.privateKey == nil { @@ -166,7 +183,7 @@ func (this CA) CreateCSR() CA { // 私钥 func (this CA) CreatePrivateKey() CA { if this.privateKey == nil { - err := errors.New("privateKey error.") + err := errors.New("privateKey empty.") return this.AppendError(err) } @@ -176,6 +193,8 @@ func (this CA) CreatePrivateKey() CA { switch privateKey := this.privateKey.(type) { case *rsa.PrivateKey: privateKeyBytes, err = x509.MarshalPKCS8PrivateKey(privateKey) + case *dsa.PrivateKey: + privateKeyBytes, err = pubkey_dsa.MarshalPKCS8PrivateKey(privateKey) case *ecdsa.PrivateKey: privateKeyBytes, err = x509.MarshalPKCS8PrivateKey(privateKey) case ed25519.PrivateKey: @@ -200,6 +219,57 @@ func (this CA) CreatePrivateKey() CA { return this } +// Create PrivateKey PEM With Password +func (this CA) CreatePrivateKeyWithPassword(password []byte, opts ...any) CA { + if this.privateKey == nil { + err := errors.New("privateKey empty.") + return this.AppendError(err) + } + + opt, err := pkcs8.ParseOpts(opts...) + if err != nil { + return this.AppendError(err) + } + + var privateKeyBytes []byte + + // 生成私钥 + switch prikey := this.privateKey.(type) { + case *rsa.PrivateKey: + privateKeyBytes, err = x509.MarshalPKCS8PrivateKey(prikey) + case *dsa.PrivateKey: + privateKeyBytes, err = pubkey_dsa.MarshalPKCS8PrivateKey(prikey) + case *ecdsa.PrivateKey: + privateKeyBytes, err = x509.MarshalPKCS8PrivateKey(prikey) + case ed25519.PrivateKey: + privateKeyBytes, err = x509.MarshalPKCS8PrivateKey(prikey) + case *sm2.PrivateKey: + privateKeyBytes, err = sm2.MarshalPrivateKey(prikey) + default: + err = errors.New("privateKey error.") + } + + if err != nil { + return this.AppendError(err) + } + + // 生成加密数据 + privateBlock, err := pkcs8.EncryptPEMBlock( + rand.Reader, + "ENCRYPTED PRIVATE KEY", + privateKeyBytes, + []byte(password), + opt, + ) + if err != nil { + return this.AppendError(err) + } + + this.keyData = pem.EncodeToMemory(privateBlock) + + return this +} + // Create PublicKey PEM func (this CA) CreatePublicKey() CA { if this.publicKey == nil { diff --git a/cryptobin/ca/from.go b/cryptobin/ca/from.go index b3f21c9..7cb3532 100644 --- a/cryptobin/ca/from.go +++ b/cryptobin/ca/from.go @@ -9,7 +9,6 @@ import ( "crypto/x509" "crypto/ecdsa" "crypto/ed25519" - "crypto/elliptic" "github.com/deatil/go-cryptobin/gm/sm2" "github.com/deatil/go-cryptobin/pkcs12" @@ -246,74 +245,70 @@ func FromSM2PKCS12Cert(pfxData []byte, password string) CA { // ======================= -// 生成密钥 RSA -// 可选 [512 | 1024 | 2048 | 4096] +// Generate RSA key +// params: +// [512 | 1024 | 2048 | 4096] func (this CA) GenerateRSAKey(bits int) CA { - // 生成私钥 - privateKey, err := rsa.GenerateKey(rand.Reader, bits) - if err != nil { - return this.AppendError(err) - } + return this.SetPublicKeyType("RSA"). + WithBits(bits). + GenerateKey() +} - this.privateKey = privateKey - this.publicKey = &privateKey.PublicKey +// Generate RSA Key +func GenerateRSAKey(bits int) CA { + return defaultCA.GenerateRSAKey(bits) +} + +// Generate DSA key +// params: +// [ L1024N160 | L2048N224 | L2048N256 | L3072N256 ] +func (this CA) GenerateDSAKey(ln string) CA { + return this.SetPublicKeyType("DSA"). + SetCurve(ln). + GenerateKey() - return this } -// 生成密钥 Ecdsa -// 可选 [P521 | P384 | P256 | P224] -func (this CA) GenerateECDSAKey(curve string) CA { - var useCurve elliptic.Curve - - switch curve { - case "P521": - useCurve = elliptic.P521() - case "P384": - useCurve = elliptic.P384() - case "P256": - useCurve = elliptic.P256() - case "P224": - useCurve = elliptic.P224() - default: - useCurve = elliptic.P256() - } +// Generate DSA Key +func GenerateDSAKey(ln string) CA { + return defaultCA.GenerateDSAKey(ln) +} - // 生成私钥 - privateKey, err := ecdsa.GenerateKey(useCurve, rand.Reader) - if err != nil { - return this.AppendError(err) - } +// Generate ECDSA key +// params: +// [P521 | P384 | P256 | P224] +func (this CA) GenerateECDSAKey(curve string) CA { + return this.SetPublicKeyType("ECDSA"). + SetCurve(curve). + GenerateKey() - this.privateKey = privateKey - this.publicKey = &privateKey.PublicKey +} - return this +// Generate ECDSA Key +func GenerateECDSAKey(curve string) CA { + return defaultCA.GenerateECDSAKey(curve) } -// 生成密钥 EdDSA +// Generate EdDSA key func (this CA) GenerateEdDSAKey() CA { - publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - return this.AppendError(err) - } + return this.SetPublicKeyType("EdDSA"). + GenerateKey() - this.privateKey = privateKey - this.publicKey = publicKey +} - return this +// Generate EdDSA Key +func GenerateEdDSAKey() CA { + return defaultCA.GenerateEdDSAKey() } -// 生成密钥 SM2 +// Generate SM2 key func (this CA) GenerateSM2Key() CA { - // 生成私钥 - privateKey, err := sm2.GenerateKey(rand.Reader) - if err != nil { - return this.AppendError(err) - } + return this.SetPublicKeyType("SM2"). + GenerateKey() - this.privateKey = privateKey - this.publicKey = &privateKey.PublicKey +} - return this +// Generate SM2 Key +func GenerateSM2Key() CA { + return defaultCA.GenerateSM2Key() } diff --git a/go.mod b/go.mod index 35fc17c..6ae4908 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,4 @@ require ( golang.org/x/text v0.21.0 ) -require golang.org/x/sys v0.28.0 // indirect +require golang.org/x/sys v0.28.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..475ef09 --- /dev/null +++ b/go.sum @@ -0,0 +1,7 @@ +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=