Skip to content

Commit

Permalink
[feature] improve rsa code
Browse files Browse the repository at this point in the history
  • Loading branch information
houseme committed Aug 11, 2021
1 parent ac5ecca commit d0ff0f8
Show file tree
Hide file tree
Showing 4 changed files with 532 additions and 45 deletions.
120 changes: 75 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@
![GitHub go.mod Go version (branch)](https://img.shields.io/github/go-mod/go-version/houseme/gocrypto/main)

## 特别说明
based on https://github.com/farmerx/gorsa, https://github.com/yuchenfw/gocrypt Optimized the following points for packaging:

based on https://github.com/farmerx/gorsa, https://github.com/yuchenfw/gocrypt Optimized the following points for
packaging:

- Optimization of public and private keys requires registration and initialization in advance.
- The encryption machine does not perform base64 processing, and avoids secondary encapsulation of base64 during cross-program transfer or storage
- The encryption machine does not perform base64 processing, and avoids secondary encapsulation of base64 during
cross-program transfer or storage
- The incoming return uses the string type uniformly to avoid conversion trouble
- Supports RSAWithSHA1 and RSAWithSHA256 signature verification algorithms

此版本新增了AES、DES、3DES、HMAC、HASH等常见加/解密及hash获取方式,结构作了些调整,由之前的版本更新到此版本时一定要注意引用方法包名的变化。
AES/DES块加密时,填充默认采用PKCS7 padding(如果块大小为64 位(8字节)时,此时PKCS7与PKCS5结果一致).
此版本新增了AES、DES、3DES、HMAC、HASH等常见加/解密及hash获取方式,结构作了些调整,由之前的版本更新到此版本时一定要注意引用方法包名的变化。 AES/DES块加密时,填充默认采用PKCS7 padding(
如果块大小为64 位(8字节)时,此时PKCS7与PKCS5结果一致).

## get & import

Expand All @@ -26,12 +30,12 @@ go get -u -v github.com/houseme/gocrypto
### 1.构建需要加解密的类型handle

```go
handleRSA := rsa.NewRSACrypt(secretInfo)//RSA
handleDES := des.NewDESCrypt(key)//des
handle3DES := des.NewTripleDESCrypt(key)//3des
handleAES := aes.NewAESCrypt(key)//aes
handleHash := hash.NewHash(hashType)//common hash
handleHMAC := hash.NewHMAC(hashType,key)//hmac
handleRSA := rsa.NewRSACrypt(secretInfo) // RSA
handleDES := des.NewDESCrypt(key) // des
handle3DES := des.NewTripleDESCrypt(key) // 3des
handleAES := aes.NewAESCrypt(key) // aes
handleHash := hash.NewHash(hashType) // common hash
handleHMAC := hash.NewHMAC(hashType, key) // hmac
```

### 2.加密、解密、hash、hmac
Expand All @@ -41,38 +45,38 @@ handleHMAC := hash.NewHMAC(hashType,key)//hmac
加密指定字符串,并以指定编码格式输出结果

```go
encrypt, err := handle.Encrypt(src)//des/3des/aes
encrypt, err := handle.Encrypt(src) // des/3des/aes
```

#### (2)解密

解密指定格式编码后的加密串,返回原字符串

```go
decrypt, err := handle.Decrypt(src)//des/3des/aes
decrypt, err := handle.Decrypt(src) // des/3des/aes
```

#### (3)hash/hmac

哈希运算/密钥相关的哈希运算。

```go
handle.Get([]byte("123456"))//输出[]byte
handle.EncodeToString([]byte("123456"),gocrypt.HEX)//输出为hex格式的字符串
handle.Get([]byte("123456"))// 输出[]byte
handle.EncodeToString([]byte("123456"), gocrypto.HEX) // 输出为hex格式的字符串
```

## RSA加密、解密、签名、验签

### 1.设置公私钥信息

```go
secretInfo := rsa.RSASecret{
PublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyoiAraTnAbCoqGVOKugFDM2/ms2szXmb3zTOU3ByicH/XPZqy7Eougbs8OQQIoNW4xKw8PNyWf0lfr90qBfPj27INn6N7umVmbHCNCKkQ4frPn46xesw1ywtc2GhOEzZlC8ajlnzBUkj5FJZcrNjXfFmfsQcFQP0g/o/3CAUpk1BXFXt7eZsaYdyn0m7fMoyFt1wlF8egQeGYYE98vtKsvrII51HK8vOEf+5VXU4UZxGfvyzS3A8kuNEkKEh1n9mazjfPBT0KGSiOGh7Nugks+jjfswSgXRK/b2eP3fS7U625rbS798pKxnoS2E0Pgpzdk5fWoNgAlG/n2F9oI2/kQIDAQAB",
PublicKeyDataType: gocrypt.Base64,
PrivateKey: "MIIEowIBAAKCAQEAyoiAraTnAbCoqGVOKugFDM2/ms2szXmb3zTOU3ByicH/XPZqy7Eougbs8OQQIoNW4xKw8PNyWf0lfr90qBfPj27INn6N7umVmbHCNCKkQ4frPn46xesw1ywtc2GhOEzZlC8ajlnzBUkj5FJZcrNjXfFmfsQcFQP0g/o/3CAUpk1BXFXt7eZsaYdyn0m7fMoyFt1wlF8egQeGYYE98vtKsvrII51HK8vOEf+5VXU4UZxGfvyzS3A8kuNEkKEh1n9mazjfPBT0KGSiOGh7Nugks+jjfswSgXRK/b2eP3fS7U625rbS798pKxnoS2E0Pgpzdk5fWoNgAlG/n2F9oI2/kQIDAQABAoIBAF378hqiR0CVhe5+9EMc4BsM7zka8HF5WUe+7W/y4nPivmmZP/29/DQ3OoSekI4zfIJrDgkCL7JqspeaqLvIMN1Sfz4qhBq18mIcBw7CdI+R5yxcz1FAzq1LJtxAFdxWbTFCmoQsYYW2Zx1wyWlcrWPOvc1dm9p0t2b3HeM8T9jLdY+D0Bm9zmAS0nwTuDBxYS77DB9Ncl6pWLLd197/5IoN1/nunFuzpkiwMPI9RF7lgrnUthc/1Gfnylz5/tXCiQsEVSbAdbMXt9nsV0RgVeMcPq/aUqTMLS2lIV8JySWDrRQi4yPHU0hIjcp6ggo53YMuncJZweI/wwkJexojz0ECgYEA5QzRObpU0CryfJ7qa97/USIKHbvl6PuQG9OLyUeP9bG0edidQhUrR4EZwjIl73O8CTJ0bB24wAKZZEOK3eJeqG/N0q+CiD83ygr8pSZzpE1xvqQp32IgXtgvm7/UmT8cfAp05Z3bF4jcA8uXwodBz4NsVGijlO78PsCooLsArM0CgYEA4lz5pXDEN3w5JwkbspLnUSUS738hne8YM0PchCaww+8sXLS9GLL2CHcvwh6Tv9Mee7r6SdbDI73x118y68WEDDhidiYZCLhXJN2v12ezJOMqH5m9wVJzQOGNv6kPV1EW1WlWxoJQGxCdzbZMLxtTbyTZe3+iAVG++8u6NWMV3dUCgYA1dm1rnQto321kGy+6Z/2OMXTNBeufGwDDDfilzZdTkNwASMhEAW7trLuXcV8bahcsymMUTUevQawOFBnYupq/lAEluSOtq5vZBAF+huAdLJptFiJT6rKFkM5j+z2jW3DJnyMz6UmXT7GTDTVqCWoaBqIFfbsY60NjXlK92YhJzQKBgQDWfQjktbSHasLw9RV0oPRklD+cBhfBgfOpZ+0En3CxR+j+MxhW1gSBQwZS5wxTIGXrEeHlo4UmUe5diExE0dRsi+ToVPM1qw6P1SuwbQd3tXSNmu0NyOWCnfblm/j4YNLFB1p9IK9s5dLRQKJxpG/ribw15FuK6n2QM5vOyIPIvQKBgE5PUzRUCCVsjKAxZOfaZQatMbSzAUSB3bNmUw+F3pDq8ibs6XXvtySowG2femlPDNL7mDMuUc9kYrtTFTQNrEsQGB55wBopX3UxzRjpXJoAQ/d+RPdrSJC7xJyu+URoFI6ae0I3bx1BzjctYU0Rv5DUh+j9leMH5N2S9vHb+vqu",
PrivateKeyType: gocrypt.PKCS1,
PrivateKeyDataType: gocrypt.Base64,
}
secretInfo := rsa.RSASecret{
PublicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyoiAraTnAbCoqGVOKugFDM2/ms2szXmb3zTOU3ByicH/XPZqy7Eougbs8OQQIoNW4xKw8PNyWf0lfr90qBfPj27INn6N7umVmbHCNCKkQ4frPn46xesw1ywtc2GhOEzZlC8ajlnzBUkj5FJZcrNjXfFmfsQcFQP0g/o/3CAUpk1BXFXt7eZsaYdyn0m7fMoyFt1wlF8egQeGYYE98vtKsvrII51HK8vOEf+5VXU4UZxGfvyzS3A8kuNEkKEh1n9mazjfPBT0KGSiOGh7Nugks+jjfswSgXRK/b2eP3fS7U625rbS798pKxnoS2E0Pgpzdk5fWoNgAlG/n2F9oI2/kQIDAQAB",
PublicKeyDataType: gocrypto.Base64,
PrivateKey: "MIIEowIBAAKCAQEAyoiAraTnAbCoqGVOKugFDM2/ms2szXmb3zTOU3ByicH/XPZqy7Eougbs8OQQIoNW4xKw8PNyWf0lfr90qBfPj27INn6N7umVmbHCNCKkQ4frPn46xesw1ywtc2GhOEzZlC8ajlnzBUkj5FJZcrNjXfFmfsQcFQP0g/o/3CAUpk1BXFXt7eZsaYdyn0m7fMoyFt1wlF8egQeGYYE98vtKsvrII51HK8vOEf+5VXU4UZxGfvyzS3A8kuNEkKEh1n9mazjfPBT0KGSiOGh7Nugks+jjfswSgXRK/b2eP3fS7U625rbS798pKxnoS2E0Pgpzdk5fWoNgAlG/n2F9oI2/kQIDAQABAoIBAF378hqiR0CVhe5+9EMc4BsM7zka8HF5WUe+7W/y4nPivmmZP/29/DQ3OoSekI4zfIJrDgkCL7JqspeaqLvIMN1Sfz4qhBq18mIcBw7CdI+R5yxcz1FAzq1LJtxAFdxWbTFCmoQsYYW2Zx1wyWlcrWPOvc1dm9p0t2b3HeM8T9jLdY+D0Bm9zmAS0nwTuDBxYS77DB9Ncl6pWLLd197/5IoN1/nunFuzpkiwMPI9RF7lgrnUthc/1Gfnylz5/tXCiQsEVSbAdbMXt9nsV0RgVeMcPq/aUqTMLS2lIV8JySWDrRQi4yPHU0hIjcp6ggo53YMuncJZweI/wwkJexojz0ECgYEA5QzRObpU0CryfJ7qa97/USIKHbvl6PuQG9OLyUeP9bG0edidQhUrR4EZwjIl73O8CTJ0bB24wAKZZEOK3eJeqG/N0q+CiD83ygr8pSZzpE1xvqQp32IgXtgvm7/UmT8cfAp05Z3bF4jcA8uXwodBz4NsVGijlO78PsCooLsArM0CgYEA4lz5pXDEN3w5JwkbspLnUSUS738hne8YM0PchCaww+8sXLS9GLL2CHcvwh6Tv9Mee7r6SdbDI73x118y68WEDDhidiYZCLhXJN2v12ezJOMqH5m9wVJzQOGNv6kPV1EW1WlWxoJQGxCdzbZMLxtTbyTZe3+iAVG++8u6NWMV3dUCgYA1dm1rnQto321kGy+6Z/2OMXTNBeufGwDDDfilzZdTkNwASMhEAW7trLuXcV8bahcsymMUTUevQawOFBnYupq/lAEluSOtq5vZBAF+huAdLJptFiJT6rKFkM5j+z2jW3DJnyMz6UmXT7GTDTVqCWoaBqIFfbsY60NjXlK92YhJzQKBgQDWfQjktbSHasLw9RV0oPRklD+cBhfBgfOpZ+0En3CxR+j+MxhW1gSBQwZS5wxTIGXrEeHlo4UmUe5diExE0dRsi+ToVPM1qw6P1SuwbQd3tXSNmu0NyOWCnfblm/j4YNLFB1p9IK9s5dLRQKJxpG/ribw15FuK6n2QM5vOyIPIvQKBgE5PUzRUCCVsjKAxZOfaZQatMbSzAUSB3bNmUw+F3pDq8ibs6XXvtySowG2femlPDNL7mDMuUc9kYrtTFTQNrEsQGB55wBopX3UxzRjpXJoAQ/d+RPdrSJC7xJyu+URoFI6ae0I3bx1BzjctYU0Rv5DUh+j9leMH5N2S9vHb+vqu",
PrivateKeyType: gocrypto.PKCS1,
PrivateKeyDataType: gocrypto.Base64,
}
```

### 加密、解密、签名、验签
Expand All @@ -82,49 +86,75 @@ decrypt, err := handle.Decrypt(src)//des/3des/aes
加密指定字符串,并以指定编码格式输出结果

```go
encrypt, err := handle.Encrypt("test", gocrypt.HEX)
if err != nil {
fmt.Println("encrypt error :", err)
return
}
fmt.Println("encrypt data :", encrypt)
encrypt, err := handle.Encrypt("test", gocrypto.HEX)
if err != nil {
fmt.Println("encrypt error :", err)
return
}
fmt.Println("encrypt data :", encrypt)
```

#### (2)RSA解密

解密指定格式编码后的加密串,返回原字符串

```go
decrypt, err := handle.Decrypt(encrypt, gocrypt.HEX)
if err != nil {
fmt.Println("decrypt error :", err)
return
}
fmt.Println("decrypt data :", decrypt)
decrypt, err := handle.Decrypt(encrypt, gocrypto.HEX)
if err != nil {
fmt.Println("decrypt error :", err)
return
}
fmt.Println("decrypt data :", decrypt)
```

#### (3)RSA签名

以指定摘要算法签名,并以指定编码格式输出结果,仅适用于RSA。

```go
sign, err := handle.Sign("test", gocrypt.SHA256, gocrypt.HEX)
if err != nil {
fmt.Println("sign error :", err)
return
}
fmt.Println("sign data :", sign)
sign, err := handle.Sign("test", gocrypto.SHA256, gocrypto.HEX)
if err != nil {
fmt.Println("sign error :", err)
return
}
fmt.Println("sign data :", sign)
```

#### (4)RSA验签

验证字符串是否是以指定摘要算法编码的签名串的原始字符串,仅适用于RSA。

```go
verifySign, err := handle.VerifySign("test", gocrypt.SHA256, sign, gocrypt.HEX)
if err != nil {
fmt.Println("verifySign error :", err)
return
}
fmt.Println("verifySign result :", verifySign)
verifySign, err := handle.VerifySign("test", gocrypto.SHA256, sign, gocrypto.HEX)
if err != nil {
fmt.Println("verifySign error :", err)
return
}
fmt.Println("verifySign result :", verifySign)
```

#### (5)RSA私钥加密

加密指定字符串,并以指定编码格式输出结果

```go
encrypt, err := handle.EncryptByPriKey("test", gocrypto.HEX)
if err != nil {
fmt.Println("encrypt error :", err)
return
}
fmt.Println("encrypt data :", encrypt)
```

#### (6)RSA公钥解密

解密指定格式编码后的加密串,返回原字符串

```go
decrypt, err := handle.DecryptByPublic(encrypt, gocrypto.HEX)
if err != nil {
fmt.Println("decrypt error :", err)
return
}
fmt.Println("decrypt data :", decrypt)
```
60 changes: 60 additions & 0 deletions rsa/rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package rsa

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
Expand Down Expand Up @@ -144,8 +145,67 @@ func (rc *rsaCrypt) VerifySign(src string, hashType gocrypto.Hash, signedData st
return false, err
}
signDecoded, err := gocrypto.DecodeString(signedData, signDataType)
if err != nil {
return false, err
}
if err = rsa.VerifyPKCS1v15(pubKey.(*rsa.PublicKey), cryptoHash, hashed, signDecoded); err != nil {
return false, err
}
return true, nil
}

// EncryptByPriKey encrypts the given message with private key
// src the original data
// outputDataType the encode type of encrypted data ,such as Base64,HEX
func (rc *rsaCrypt) EncryptByPriKey(src string, outputDataType gocrypto.Encode) (dst string, err error) {
secretInfo := rc.secretInfo
if secretInfo.PrivateKey == "" {
return "", fmt.Errorf("secretInfo PrivateKey can't be empty")
}
privateKeyDecoded, err := gocrypto.DecodeString(secretInfo.PrivateKey, secretInfo.PrivateKeyDataType)
if err != nil {
return
}
prvKey, err := gocrypto.ParsePrivateKey(privateKeyDecoded, secretInfo.PrivateKeyType)
if err != nil {
return
}

output := bytes.NewBuffer(nil)
err = priKeyIO(prvKey, bytes.NewReader([]byte(src)), output, true)
if err != nil {
return "", err
}

return gocrypto.EncodeToString(output.Bytes(), outputDataType)
}

// DecryptByPublic decrypts a plaintext using public key
// src the encrypted data with private key
// srcType the encode type of encrypted data ,such as Base64,HEX
func (rc *rsaCrypt) DecryptByPublic(src string, srcType gocrypto.Encode) (dst string, err error) {
secretInfo := rc.secretInfo
if secretInfo.PublicKey == "" {
return "", fmt.Errorf("secretInfo PublicKey can't be empty")
}
pubKeyDecoded, err := gocrypto.DecodeString(secretInfo.PublicKey, secretInfo.PublicKeyDataType)
if err != nil {
return
}
pubKey, err := x509.ParsePKIXPublicKey(pubKeyDecoded)
if err != nil {
return
}

decodeData, err := gocrypto.DecodeString(src, srcType)
if err != nil {
return
}

output := bytes.NewBuffer(nil)
err = pubKeyIO(pubKey.(*rsa.PublicKey), bytes.NewReader(decodeData), output, false)
if err != nil {
return "", err
}
return output.String(), nil
}
Loading

0 comments on commit d0ff0f8

Please sign in to comment.