Skip to content

Commit 776359b

Browse files
authored
新增 RSA PKCS1 加解密功能以兼容境外接口
1 parent d398bc6 commit 776359b

2 files changed

Lines changed: 101 additions & 15 deletions

File tree

utils/rsa_crypto.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"fmt"
1212
)
1313

14-
// EncryptOAEPWithPublicKey 使用公钥进行加密
14+
// EncryptOAEPWithPublicKey 使用 OAEP padding方式用公钥进行加密
1515
func EncryptOAEPWithPublicKey(message string, publicKey *rsa.PublicKey) (ciphertext string, err error) {
1616
if publicKey == nil {
1717
return "", fmt.Errorf("you should input *rsa.PublicKey")
@@ -24,7 +24,7 @@ func EncryptOAEPWithPublicKey(message string, publicKey *rsa.PublicKey) (ciphert
2424
return ciphertext, nil
2525
}
2626

27-
// EncryptOAEPWithCertificate 先解析出证书中的公钥,然后使用公钥进行加密
27+
// EncryptOAEPWithCertificate 先解析出证书中的公钥,然后使用 OAEP padding方式公钥进行加密
2828
func EncryptOAEPWithCertificate(message string, certificate *x509.Certificate) (ciphertext string, err error) {
2929
if certificate == nil {
3030
return "", fmt.Errorf("you should input *x509.Certificate")
@@ -36,6 +36,31 @@ func EncryptOAEPWithCertificate(message string, certificate *x509.Certificate) (
3636
return EncryptOAEPWithPublicKey(message, publicKey)
3737
}
3838

39+
// EncryptPKCS1v15WithPublicKey 使用PKCS1 padding方式用公钥进行加密
40+
func EncryptPKCS1v15WithPublicKey(message string, publicKey *rsa.PublicKey) (ciphertext string, err error) {
41+
if publicKey == nil {
42+
return "", fmt.Errorf("you should input *rsa.PublicKey")
43+
}
44+
ciphertextByte, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(message))
45+
if err != nil {
46+
return "", fmt.Errorf("encrypt message with public key err:%s", err.Error())
47+
}
48+
ciphertext = base64.StdEncoding.EncodeToString(ciphertextByte)
49+
return ciphertext, nil
50+
}
51+
52+
// EncryptPKCS1v15WithCertificate 先解析出证书中的公钥,然后使用PKCS1 padding方式用公钥进行加密
53+
func EncryptPKCS1v15WithCertificate(message string, certificate *x509.Certificate) (ciphertext string, err error) {
54+
if certificate == nil {
55+
return "", fmt.Errorf("you should input *x509.Certificate")
56+
}
57+
publicKey, ok := certificate.PublicKey.(*rsa.PublicKey)
58+
if !ok {
59+
return "", fmt.Errorf("certificate is invalid")
60+
}
61+
return EncryptPKCS1v15WithPublicKey(message, publicKey)
62+
}
63+
3964
// DecryptOAEP 使用私钥进行解密
4065
func DecryptOAEP(ciphertext string, privateKey *rsa.PrivateKey) (message string, err error) {
4166
if privateKey == nil {
@@ -51,3 +76,19 @@ func DecryptOAEP(ciphertext string, privateKey *rsa.PrivateKey) (message string,
5176
}
5277
return string(messageBytes), nil
5378
}
79+
80+
// DecryptPKCS1v15 使用私钥对PKCS1 padding方式加密的字符串进行解密
81+
func DecryptPKCS1v15(ciphertext string, privateKey *rsa.PrivateKey) (message string, err error) {
82+
if privateKey == nil {
83+
return "", fmt.Errorf("you should input *rsa.PrivateKey")
84+
}
85+
decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertext)
86+
if err != nil {
87+
return "", fmt.Errorf("base64 decode failed, error=%s", err.Error())
88+
}
89+
messageBytes, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, decodedCiphertext)
90+
if err != nil {
91+
return "", fmt.Errorf("decrypt ciphertext with private key err:%s", err)
92+
}
93+
return string(messageBytes), nil
94+
}

utils/rsa_crypto_test.go

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
package utils
44

55
import (
6+
"crypto/rand"
7+
"crypto/rsa"
8+
"crypto/sha1"
9+
"crypto/x509"
10+
"encoding/base64"
11+
"fmt"
612
"testing"
713

814
"github.com/stretchr/testify/assert"
@@ -67,34 +73,73 @@ fHMq4tsbKO0dKAeydPM/nrUZBmaYQVKMVOORGLFjFKVO7JV6Kq/R86ouhjEPgJOe
6773
2xulNBUcjicqtZlBdEh/PWCYP2SpGVDclKm8jeo175T3EVAkdKzzmfpxtMmnMlmq
6874
cTJOU9TxuGvNASMtjj7pYIerTx+xgZDXEVBWFW9PjJ0TV06tCRsgSHItgg==
6975
-----END CERTIFICATE-----`
76+
testRSACryptoUtilPrivateKey *rsa.PrivateKey
77+
testRSACryptoUtilPublicKey *rsa.PublicKey
78+
testRSACryptoUtilCertificate *x509.Certificate
7079
)
7180

72-
func TestEncryptAndDecrypt(t *testing.T) {
73-
privatKey, err := LoadPrivateKey(testingKey(testRSACryptoUtilPrivateKeyStr))
81+
func init() {
82+
var err error
83+
testRSACryptoUtilPrivateKey, err = LoadPrivateKey(testingKey(testRSACryptoUtilPrivateKeyStr))
84+
if err != nil {
85+
panic(fmt.Errorf("fail to load the private key:%s", err.Error()))
86+
}
87+
testRSACryptoUtilPublicKey, err = LoadPublicKey(testRSACryptoUtilPublicKeyStr)
88+
if err != nil {
89+
panic(fmt.Errorf("fail to load the public key:%s", err.Error()))
90+
}
91+
testRSACryptoUtilCertificate, err = LoadCertificate(testRSACryptoUtilMchCertificateStr)
92+
if err != nil {
93+
panic(fmt.Errorf("fail to load the certificate key:%s", err.Error()))
94+
}
95+
}
96+
97+
func TestOAEPCrypto(t *testing.T) {
98+
99+
const message = "hello world"
100+
// 使用OAEP padding方式对证书加密
101+
ciphertext, err := EncryptOAEPWithCertificate(message, testRSACryptoUtilCertificate)
74102
require.NoError(t, err)
75103

76-
publicKey, err := LoadPublicKey(testRSACryptoUtilPublicKeyStr)
104+
// 使用OAEP padding方式用公有库直接进行私钥解密,以验证加密正确
105+
decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertext)
77106
require.NoError(t, err)
107+
decryptMessageBytes, err := rsa.DecryptOAEP(
108+
sha1.New(), rand.Reader, testRSACryptoUtilPrivateKey, decodedCiphertext, nil)
109+
require.NoError(t, err)
110+
assert.Equal(t, message, string(decryptMessageBytes))
78111

79-
certificate, err := LoadCertificate(testRSACryptoUtilMchCertificateStr)
112+
// 使用OAEP padding方式直接公钥加密
113+
ciphertext, err = EncryptOAEPWithPublicKey(message, testRSACryptoUtilPublicKey)
80114
require.NoError(t, err)
81115

116+
// 使用OAEP padding方式私钥解密
117+
decryptMessage, err := DecryptOAEP(ciphertext, testRSACryptoUtilPrivateKey)
118+
require.NoError(t, err)
119+
assert.Equal(t, message, decryptMessage)
120+
}
121+
122+
func TestPKCS1v15Crypto(t *testing.T) {
123+
82124
const message = "hello world"
83-
// 使用证书加密
84-
cipertext, err := EncryptOAEPWithCertificate(message, certificate)
125+
126+
// 使用PKCS1 padding对证书加密
127+
ciphertext, err := EncryptPKCS1v15WithCertificate(message, testRSACryptoUtilCertificate)
85128
require.NoError(t, err)
86129

87-
// 私钥解密
88-
decryptMessage, err := DecryptOAEP(cipertext, privatKey)
130+
// 使用PKCS1 padding对用公有库直接进行私钥解密,以验证加密正确
131+
decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertext)
89132
require.NoError(t, err)
90-
assert.Equal(t, message, decryptMessage)
133+
decryptMessageBytes, err := rsa.DecryptPKCS1v15(rand.Reader, testRSACryptoUtilPrivateKey, decodedCiphertext)
134+
require.NoError(t, err)
135+
assert.Equal(t, message, string(decryptMessageBytes))
91136

92-
// 直接公钥加密
93-
cipertext, err = EncryptOAEPWithPublicKey(message, publicKey)
137+
// 使用PKCS1 padding进行公钥加密
138+
ciphertext, err = EncryptPKCS1v15WithPublicKey(message, testRSACryptoUtilPublicKey)
94139
require.NoError(t, err)
95140

96-
// 私钥解密
97-
decryptMessage, err = DecryptOAEP(cipertext, privatKey)
141+
// 使用PKCS1 padding进行私钥解密
142+
decryptMessage, err := DecryptPKCS1v15(ciphertext, testRSACryptoUtilPrivateKey)
98143
require.NoError(t, err)
99144
assert.Equal(t, message, decryptMessage)
100145
}

0 commit comments

Comments
 (0)