golang中关于RSA加密、解密、签名、验签的通用处理方式

前言

我在golang中关于RSA加密、解密、签名、验签的总结一文中介绍了常见的一些使用情况,并做了一些针对性的方法实例。但鉴于实例中部分参数稍微变化则需要调整整个方法,本文则从通用的角度去处理这些差异点,正确在可设置的范围内实现通用的方法。

项目地址:gocrypt,欢迎star和fork。

方案说明

RSA目前常用的就是加密、解密、签名、验签相关的内容,我们则从这4个方向去做通用的解决方案。以下是具体的情况总结,与前言中提到的文章有关

1.私钥的格式

(1) PKCS1

(2) PKCS8

两者可以相互转化,PKCS8主要用于JAVA中,PKCS1用于其他语言中,当然golang中两种格式都可以使用

2.摘要算法

目前最常用的摘要算法方式如下:

(1) MD5

(2) SHA1

(3) SHA256

(3) SHA512

如目前支付宝中:使用了RSA(SHA1)和RSA2(SHA256)两种签名算法,秘钥越长,摘要的长度越长,信息越安全。

3.字符串编码格式

目前最常用的信息编码格式如下:

(1) 直接输出为string

(2) 经过HEX编码后转为string

(3) 经过Base64编码后转为string

方案设计

我们针对方案说明中的情况均做了处理,作为可设置项。一下代码对应相应的设置项。

//私钥格式
type Secret uint
const (
	PKCS1 Secret = 1 + iota
	PKCS8
)

//摘要算法,对应crypto package内的算法
type Hash uint
const (
	MD5        Hash = 1 + iota
	SHA1
	SHA224
	SHA256
	SHA384
	SHA512
	SHA512_224
	SHA512_256
)

//字符串编码格式
type Encode uint
const (
	None Encode = 1 + iota
	HEX
	Base64
)

同时考虑到更一般的使用情况,我们把秘钥信息单独开来,

//SecretInfo private & public key info
type SecretInfo struct {
	PublicKey          string //公钥
	PublicKeyDataType  Encode //公钥编码格式
	PrivateKey         string //私钥
	PrivateKeyDataType Encode //私钥编码格式
	PrivateKeyType     Secret //私钥类型
}

考虑到后期我们可能会加入RSA之外的加密算法如DES(事实上,我正在准备加入),我们使用接口,便于扩展。

type HandleFunc interface {
	setSecretInfo(secretInfo SecretInfo)
	Encrypt(inputData string, outputDataType Encode) (string, error)
	Decrypt(inputData string, inputDataType Encode) (string, error)
	Sign(inputData string, hashType Hash, outputDataType Encode) (string, error)
	VerifySign(inputData string, hashType Hash, signData string, signDataType Encode) (bool, error)
}

我把这些内容提交到github中的gocrypt项目了,rsa中具体的实现见gocrypt代码,欢迎star和fork。

使用说明

更具体的说明见github gocrypt哦。

使用方法

go get github.com/yuchenfw/gocrypt

1.设置公私钥信息

    secretInfo := gocrypt.SecretInfo{
		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,
	}

2.构造handle

handle, err := gocrypt.NewCrypt(gocrypt.RSA, secretInfo)
	if err != nil {
		fmt.Println("new error :", err)
		return
	}

3.加密、解密、签名、验签

(1)加密

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

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

(2)解密

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

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

(3)签名

以指定摘要算法签名,并以指定编码格式输出结果

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

(4)验签

验证字符串是否是以指定摘要算法编码的签名串的原始字符串

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

你可能感兴趣的:(golang)