go语言RSA分段加密V2501,GOLANG,RSA/ECB/PKCS1Padding。
加密解析:
//假设私钥长度为1024, 1024/8-11=117。
//如果明文的长度小于117,直接全加密,然后转base64。(data.Length <= maxBlockSize)
//如果明文长度大于117,则每117分一段加密,
publicKey.Size()刚好是(私钥长度/8)。privateKey.Size() 也一样。
解密解析:
//假设私钥长度为1024, 1024/8 =128。
//如果明文的长度小于 128,直接全解密。(data.Length <= maxBlockSize)
//如果明文长度大于 128,则每 128 分一段解密,
用“支付宝开放平台开发助手”生成一组公私钥:
PKCS8私钥:
MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==
与之匹配的 PKCS1 私钥,用助手转换的:
MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=
与之匹配的公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB
核心重点是拿到 GO 的 *rsa.PublicKey 、*rsa.PrivateKey 2个对象。
注意:和C#一样,公钥要还原为完整格式。
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0x KR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7 sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme 9lNAViRcj4bXfqnZqwIDAQAB -----END PUBLIC KEY-----
否则转成 *rsa.PublicKey 时会报错。
代码:
package main import ( "bytes" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "log" "strings" ) func main() { strOrg := "This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07.This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07。测试123abc" log.Println("待加密的字符串:", strOrg) strPrivateKeyPKCS1 := "MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=" strPublicKey := "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB" //和C#一样,公钥要还原为完整格式。 strPublicKey2 := PubKeyFullToPure(strPublicKey) //格式化为纯字符串 strPublicKey2 = PubKeyPureStrToFull(strPublicKey2) //还原为完整格式 fmt.Println("公钥完整格式:\n", strPublicKey2) rsaPub, err := convertPEMToRSAPublicKey(strPublicKey2) //从字符串转换为“公钥对象” if err != nil { log.Println("转换公钥时出错:", err) return } log.Println("私钥长度:", rsaPub.N.BitLen()) privateKeyBytes, _ := base64.StdEncoding.DecodeString(strPrivateKeyPKCS1) privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBytes) if err != nil { log.Println("转换私钥时出错:", err) return } bData, err := RsaEncryptBlock([]byte(strOrg), rsaPub) if err != nil { log.Println("加密时出错:", err) } encryptedString := base64.StdEncoding.EncodeToString(bData) fmt.Println("密文:") fmt.Println(encryptedString) byteDecode, _ := base64.StdEncoding.DecodeString(encryptedString) dData, err2 := RsaDecryptBlock(byteDecode, privateKey) if err2 == nil { fmt.Println("解密出的内容:") fmt.Println(string(dData)) } else { log.Println("解密时出错:", err2) } } // 格式化为纯字符串 func PubKeyFullToPure(pubKeyStr string) string { a := strings.ReplaceAll(pubKeyStr, "-----BEGIN PUBLIC KEY-----", "") a = strings.ReplaceAll(a, "-----END PUBLIC KEY-----", "") a = strings.ReplaceAll(a, "\n", "") return a } // 将 PEM 格式的公钥字符串转换为 rsa.PublicKey func convertPEMToRSAPublicKey(pemStr string) (*rsa.PublicKey, error) { // 解码 PEM 格式的字符串 block, _ := pem.Decode([]byte(pemStr)) if block == nil || block.Type != "PUBLIC KEY" { return nil, fmt.Errorf("failed to decode PEM block containing the public key") } // 解析公钥 pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } // 类型断言为 rsa.PublicKey rsaPub, ok := pub.(*rsa.PublicKey) if !ok { return nil, fmt.Errorf("not a valid RSA public key") } return rsaPub, nil } // 还原为完整格式 func PubKeyPureStrToFull(pubKeyStr string) string { // 获取公钥字符串的长度 nKeyLen := len(pubKeyStr) var finalBuffer bytes.Buffer finalBuffer.WriteString("-----BEGIN PUBLIC KEY-----\n") // 由于我们已经知道要在每 64 个字符后插入换行符,我们可以直接这样做: for i := 0; i < nKeyLen; i += 64 { end := i + 64 if end > nKeyLen { end = nKeyLen } currLine := pubKeyStr[i:end] finalBuffer.WriteString(currLine) finalBuffer.WriteString("\n") } // 写入尾部 finalBuffer.WriteString("-----END PUBLIC KEY-----\n") // 获取最终的字符串 allKeyStr := finalBuffer.String() return allKeyStr } /* * 公钥加密-分段 */ func RsaEncryptBlock(src []byte, publicKey *rsa.PublicKey) (bytesEncrypt []byte, err error) { keySize, srcSize := publicKey.Size(), len(src) //单次加密的长度 私钥长度/8 -11 。私钥长度,如:1024、2048。 publicKey.Size()刚好是(私钥长度/8)。 offSet, blockSize := 0, keySize-11 buffer := bytes.Buffer{} for offSet < srcSize { endIndex := offSet + blockSize if endIndex > srcSize { endIndex = srcSize } // 加密一部分 bytesOnce, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src[offSet:endIndex]) if err != nil { return nil, err } buffer.Write(bytesOnce) offSet = endIndex } bytesEncrypt = buffer.Bytes() return } /* * 私钥解密-分段 */ func RsaDecryptBlock(src []byte, privateKey *rsa.PrivateKey) (bytesDecrypt []byte, err error) { //分段解密,单块长度是(私钥长度/8),privateKey.Size()正好是(私钥长度/8)。 blockSize := privateKey.Size() srcSize := len(src) // log.Println("密钥长度:", blockSize, "\t密文长度:\t", srcSize) var offSet = 0 var buffer = bytes.Buffer{} for offSet < srcSize { endIndex := offSet + blockSize if endIndex > srcSize { endIndex = srcSize } bytesOnce, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, src[offSet:endIndex]) if err != nil { return nil, err } buffer.Write(bytesOnce) offSet = endIndex } bytesDecrypt = buffer.Bytes() return }
运行结果:
2025/01/09 13:39:51 待加密的字符串: This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07.This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07。测试123abc 2025/01/09 13:39:51 私钥长度: 1024 密文: DMUH3zB2Eis9KT7GQ8jDFuJ2ZOZNLa/fpDzZl3oBsIVwH8uKDY8whwbYJzjXcL5EMhqpsHUNe+O8r7lN3JjYwsQlXAdRxALHvwptvW4Li8Qq5bn/RngqWiGt4AOgBK/Qm/pBhZIw1j0RTDQoZqmpNp2Rybtjw1aSoKJAvEbuGF+J7NYV8Nosl64+ZWDNDJNIhV08XAU8zw2qDd8ixGLpDd4mtrCArJ+NiHOfz7KZL2H9y23FOWnafwvdGJtWpx/R3aTjIv80INCW1xEG78qPUZx62+oHfjORwY5oTSibi49eiEW6kuDP2EQbW90130ZDkSLM6uak21cgvkDb58RzNYFonIi2Q7znzPpKF8eKWZ5fjyC7+v8kdBgqg0e6dhEi6uReO30ibT+/cl5kiQnywLbB5NALwLotmTmonPkYYGGkJF2vSZ7hy/HUgiZ506AVN/U5gDVQC3ffpd76LOD1quLnkYoRdJQ0MgB0tPj8Q+4yaTeUgdOC3TpKrdxf3pvPcyJxXBJFJ5gA+enV1iTzZBrxi12uTsF4g9f0npxRTV7Gr8GitvBeTekRnK+i8FCFa3MT9IFO9c4D/m7a8PCNWNMYcKl6SMX+F3bNYiiPR3nKHxi7o/3hZTHBggCqPpILR3P/VfnUc/y51KpCICaH0YrfOHrTiMzpVZGxitn1Uv8= 解密出的内容: This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07.This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07This is a very long message that needs to be encrypted using RSA in multiple parts.中华人民共和国2025-01-07。测试123abc
--
标签:私钥,err,nil,V2501,RSA,-----,go,return From: https://www.cnblogs.com/runliuv/p/18662005