From 06d402e18f1ee31e2e7888feb5a7922275626278 Mon Sep 17 00:00:00 2001 From: loveuer Date: Thu, 11 Dec 2025 18:49:47 +0800 Subject: [PATCH] feat: add LoadRSACrt --- tool/rsa.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ tool/rsa_test.go | 19 +++++++++++++ 2 files changed, 88 insertions(+) diff --git a/tool/rsa.go b/tool/rsa.go index e5fd223..72eef1d 100644 --- a/tool/rsa.go +++ b/tool/rsa.go @@ -184,3 +184,72 @@ func RSADecrypt(encryptedBase64 string, cfg *tls.Config) ([]byte, error) { return decrypted, nil } + +func LoadRSACertificate(pubKeyBytes, priKeyBytes []byte) (*rsa.PublicKey, *rsa.PrivateKey, error) { + var ( + err error + pubKey *rsa.PublicKey + priKey *rsa.PrivateKey + ) + + if len(pubKeyBytes) == 0 && len(priKeyBytes) == 0 { + return nil, nil, errors.New("both public and private key bytes are empty") + } + + if len(pubKeyBytes) > 0 { + pubKey, err = parsePublicKey(pubKeyBytes) + if err != nil { + return nil, nil, err + } + } + + if len(priKeyBytes) > 0 { + priKey, err = parsePrivateKey(priKeyBytes) + if err != nil { + return nil, nil, err + } + } + + return pubKey, priKey, nil +} + +func parsePublicKey(pubKeyBytes []byte) (*rsa.PublicKey, error) { + block, _ := pem.Decode(pubKeyBytes) + if block == nil { + return nil, errors.New("failed to decode public key") + } + + pubKey, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + + rsaPubKey, ok := pubKey.(*rsa.PublicKey) + if !ok { + return nil, errors.New("not an RSA public key") + } + + return rsaPubKey, nil +} + +func parsePrivateKey(priKeyBytes []byte) (*rsa.PrivateKey, error) { + block, _ := pem.Decode(priKeyBytes) + if block == nil { + return nil, errors.New("failed to decode private key") + } + + priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + priKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + } + + rsaPriKey, ok := priKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("not an RSA private key") + } + + return rsaPriKey, nil +} diff --git a/tool/rsa_test.go b/tool/rsa_test.go index 2d59533..e7c9692 100644 --- a/tool/rsa_test.go +++ b/tool/rsa_test.go @@ -41,3 +41,22 @@ func TestRSA(t *testing.T) { t.Fatalf("Original and decrypted data don't match, org1 = %s, org2 = %s", org, org2) } } + +func TestLoadRSACertificate(t *testing.T) { + const ( + pubKey = `-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwJZyF1WhhsmtDpTfmvGnGIcLHIK/QLYV7Xy3O7Cwb28fxcbHw7z+1WHdbE65QxIAUvh9niR8EzAZyLOD2ZOrXdKyz4cZ48YjisNeGxf2x61uX0Ao6JZsbNjyp3NJCcyLmenDO8BCzPaj1UJ6nkDO53/W494UJ8nKVB726JCWdBCKSijOWutBvxYqC1bZHs/etQ8KwWPiBiEthV/6hHnlzm9oGfKfHapB6eNTtzKjrl39cuKwZwlbDo3R2Xe8bK8ATwkCbGq2EGdWuNKt94dPVH8f+RhqkEdnR4mJrTFVNifWLcPi2dTNCaP8Q87KlI4dnzyq0uo3gS9U7bvIVSH6HhhmwLN33WzZsUnQ+laVTZqOmwuNZosc8BQ4k2Bu+w4ZobjkY7dTJDG+JHuMKH9W9zzu5eF/1oVA9zd6Gi1nYo/G+y/UaaBLXdqaQijZFQHmRWGI+rvKN0tl6Ruw1pFjvrEd/kBYpfIl5BIPX2D0ElSTfXACjb4TcEoMGMGjbr6awjzb0X6Z6hVzuWN1oJcaMFat0VInNdjiG7o6EvgW3DKiSWiRaRAxaF+d1pp7wIRipLKQbp9VCp8OPAVXLRuma4R/VDqpVt53i0tJGBbR+ICixdKUp6hszOgup0DClSLSwQv30SXEWcJSPf+x1Y1kdS9XytqkJwuyO7IirFAZXZ0CAwEAAQ== +-----END PUBLIC KEY-----` + priKey = `-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY-----` + ) + + pub, pri, err := LoadRSACertificate(StringToBytes(pubKey), StringToBytes(priKey)) + if err != nil { + t.Fatal(err) + } + + t.Logf("Public Key: %#v", pub) + t.Logf("Private Key: %#v", pri) +}