rsa数据加密无大小限制——golang实现

由于rsa加密需要公钥长度大于消息长度,消息太长时经常会报错Message too long for RSA
采用分块的方法,将消息分成更小的块,解决这个问题

package xrsa
import ("encoding/pem""encoding/base64""crypto/x509""crypto/rsa""crypto/rand""errors""crypto""io""bytes""encoding/asn1"
)
const (CHAR_SET = "UTF-8"BASE_64_FORMAT = "UrlSafeNoPadding"RSA_ALGORITHM_KEY_TYPE = "PKCS8"RSA_ALGORITHM_SIGN = crypto.SHA256
)
type XRsa struct {publicKey *rsa.PublicKeyprivateKey *rsa.PrivateKey
}
// 生成密钥对
func CreateKeys(publicKeyWriter, privateKeyWriter io.Writer, keyLength int) error {// 生成私钥文件privateKey, err := rsa.GenerateKey(rand.Reader, keyLength)if err != nil {return err}derStream := MarshalPKCS8PrivateKey(privateKey)block := &pem.Block{Type:  "PRIVATE KEY",Bytes: derStream,}err = pem.Encode(privateKeyWriter, block)if err != nil {return err}// 生成公钥文件publicKey := &privateKey.PublicKeyderPkix, err := x509.MarshalPKIXPublicKey(publicKey)if err != nil {return err}block = &pem.Block{Type:  "PUBLIC KEY",Bytes: derPkix,}err = pem.Encode(publicKeyWriter, block)if err != nil {return err}return nil
}
func NewXRsa(publicKey []byte, privateKey []byte) (*XRsa, error) {block, _ := pem.Decode(publicKey)if block == nil {return nil, errors.New("public key error")}pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {return nil, err}pub := pubInterface.(*rsa.PublicKey)block, _ = pem.Decode(privateKey)if block == nil {return nil, errors.New("private key error!")}priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)if err != nil {return nil, err}pri, ok := priv.(*rsa.PrivateKey)if ok {return &XRsa {publicKey: pub,privateKey: pri,}, nil} else {return nil, errors.New("private key not supported")}
}
// 公钥加密
func (r *XRsa) PublicEncrypt(data string) (string, error) {partLen := r.publicKey.N.BitLen() / 8 - 11chunks := split([]byte(data), partLen)buffer := bytes.NewBufferString("")for _, chunk := range chunks {bytes, err := rsa.EncryptPKCS1v15(rand.Reader, r.publicKey, chunk)if err != nil {return "", err}buffer.Write(bytes)}return base64.RawURLEncoding.EncodeToString(buffer.Bytes()), nil
}
// 私钥解密
func (r *XRsa) PrivateDecrypt(encrypted string) (string, error) {partLen := r.publicKey.N.BitLen() / 8raw, err := base64.RawURLEncoding.DecodeString(encrypted)chunks := split([]byte(raw), partLen)buffer := bytes.NewBufferString("")for _, chunk := range chunks {decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, chunk)if err != nil {return "", err}buffer.Write(decrypted)}return buffer.String(), err
}
// 数据加签
func (r *XRsa) Sign(data string) (string, error) {h := RSA_ALGORITHM_SIGN.New()h.Write([]byte(data))hashed := h.Sum(nil)sign, err := rsa.SignPKCS1v15(rand.Reader, r.privateKey, RSA_ALGORITHM_SIGN, hashed)if err != nil {return "", err}return base64.RawURLEncoding.EncodeToString(sign), err
}
// 数据验签
func (r *XRsa) Verify(data string, sign string) error {h := RSA_ALGORITHM_SIGN.New()h.Write([]byte(data))hashed := h.Sum(nil)decodedSign, err := base64.RawURLEncoding.DecodeString(sign)if err != nil {return err}return rsa.VerifyPKCS1v15(r.publicKey, RSA_ALGORITHM_SIGN, hashed, decodedSign)
}
func MarshalPKCS8PrivateKey(key *rsa.PrivateKey) []byte {info := struct {Version             intPrivateKeyAlgorithm []asn1.ObjectIdentifierPrivateKey          []byte}{}info.Version = 0info.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 1)info.PrivateKeyAlgorithm[0] = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}info.PrivateKey = x509.MarshalPKCS1PrivateKey(key)k, _ := asn1.Marshal(info)return k
}
func split(buf []byte, lim int) [][]byte {var chunk []bytechunks := make([][]byte, 0, len(buf)/lim+1)for len(buf) >= lim {chunk, buf = buf[:lim], buf[lim:]chunks = append(chunks, chunk)}if len(buf) > 0 {chunks = append(chunks, buf[:len(buf)])}return chunks
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/751218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划题目集一(代码 注解)

目录 介绍: 题目一: 题目二: 题目三: 题目四: 题目五: 题目六: 题目七: 题目八: 题目九: 介绍: 动态规划是一种算法设计技术,用于解决具有重叠…

水泵房远程监控物联网系统

随着物联网技术的快速发展,越来越多的行业开始利用物联网技术实现设备的远程监控与管理。水泵房作为城市供水系统的重要组成部分,其运行状态的监控与管理至关重要。HiWoo Cloud作为专业的物联网云服务平台,为水泵房远程监控提供了高效、稳定、…

音乐播放器-C#实现

音乐播放器-C#实现 目录 一、 代码介绍 二、 音乐播放器-C#实现 三、 音乐播放器-C#实现 四、 音乐播放器-C#实现 五、 音乐播放器-C#实现 代码介绍 代码中使用了.NET框架中的System.Media命名空间来处理音频文件的播放和控制。这段代码创建了一个简单的音乐播放器界…

Java访问数据库(重点:SpringBoot整合Mybatis)

目录 一、通过JDBC访问数据库1、思路2、示例3、思考 二、通过ORM框架访问数据库(主要是Mybatis)1、示例1.1 配置1.2 SQL写在xxxMapper.xml中:mapper/UserMapper.xml1.3 xxxMapper.xml对应的xxxMapper接口(Application通过该接口访…

C#设计原则

学习设计原则是学习设计模式的基础。在实际的开发过程中,并不是一定要求所有的代码都遵循设计原则,而是要综合考虑人力、成本、时间、质量,不刻意追求完美,要在适当的场景遵循设计原则。 这体现的是一种平衡取舍,可以…

SRE运维揭秘: 企业生产中运维监控的真相

大家好,我是博哥爱运维,有着十年SRE运维开发经验,从事过全球多个主流云平台的服务架构设计及自动化运维开发工作,在企业中基于gitlab和k8s从零设计过完整的一套CICD流水线架构,曾用shell开发过运维堡垒机系统&#xff…

磁盘未格式化,数据恢复有妙招

一、初遇磁盘未格式化,惊慌失措 在日常生活和工作中,我们经常会使用各种存储设备来保存重要的文件和数据。然而,有时当我们尝试访问这些存储设备时,却会突然遇到一个令人头痛的问题——磁盘未格式化。这个突如其来的提示让我们措…

虚拟函数和普通函数的区别?内联函数和构造函数能否成为虚拟函数?

虚拟函数和普通函数的区别主要在于它们的调用方式。当一个类中有虚拟函数时,编译器会为该类创建一个虚函数表(vtable),这个表中存储了该类中所有虚拟函数的地址。在运行时,通过基类的指针或引用调用派生类中的函数时&a…

[Python初阶]2255.统计是给定字符串前缀的字符串数目

目录 2255.统计是给定字符串前缀的字符串数目 ①.题目 ②.问题分析 ③.startswith()方法理解 与 说明 Ⅰ.定义和用法 Ⅱ.语法 ④.问题解决 ⑤总结 2255.统计是给定字符串前缀的字符串数目 ①.题目 ②.问题分析 需求:统计列表words中,是字符串s的前缀的字符串的数目. 解…

【解惑】离线版本的软件如何实现“授权验证”和“使用有效期”验证的

如何实现 要实现软件授权验证和使用有效期验证的离线版本,可以考虑以下几个步骤: 授权验证: 在软件的离线版本中,可以通过在软件中嵌入一个授权验证模块来进行验证。授权验证模块可以包含一个加密算法,用于生成和验证…

接口与多态

通过接口实现多态 接口中声明若干个 bstract方法; 方法体的内容细节由实现接口的类去完成,不同的类有 不同的实现方式 → 则接口变量在回调接口方法时具有多 种形态。 用接口进行程序设计的核心思想 使用接口回调技术:接口变量存放实现该接口…

(学习日记)2024.03.13:UCOSIII第十五节:基于时基列表的时延操作(持续更新)

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

Redis集群原理解析

一、单机Redis存在的问题 问题1:数据丢失问 解决方案:利用RDB和AOF实现数据的持久化 问题2:并发能力弱 解决方案:搭建主从集群,实现主从分离 问题3:存储空间小 解决方案:搭建分片集群&#xff0…

KY191 矩阵幂(用Java实现)

描述 给定一个n*n的矩阵&#xff0c;求该矩阵的k次幂&#xff0c;即P^k。 输入描述&#xff1a; 第一行&#xff1a;两个整数n&#xff08;2<n<10&#xff09;、k&#xff08;1<k<5&#xff09;&#xff0c;两个数字之间用一个空格隔开&#xff0c;含义如上所示…

《LeetCode热题100》笔记题解思路技巧优化_Part_3

《LeetCode热题100》笔记&题解&思路&技巧&优化_Part_3 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题链表&#x1f7e2;1. 相交链表&#x1f7e2;2. 反转链表&…

大数据数据分析-scala、IDEA、jdk之间的搭配关系

Scala主要是一门面向对象编程语言和函数式编程语言。 一、大数据框架&#xff08;处理海量/流式数据&#xff09; - ---以HADOOP 2. x为系列的大数据生态系统处理框架 离线数据分析&#xff0c;分析的数据为N1天数据 -----MapReduce 并行计算框架&#xff0c;分而治之…

数据治理系统论-结合数据要素等

什么是数据治理&#xff1f; 数据治理是指组织内外部对数据进行管理和监控的全面框架。它涵盖了数据的安全、合规性、可用性和价值最大化等方面。通过有效的数据治理&#xff0c;组织能够更好地理解其数据资产&#xff0c;并确保数据被正确地管理和利用。 数据治理的重要性 在…

django实现api接口

&#xff08;前期准备&#xff09;第一步&#xff1a;虚拟环境 在windows上使用virtualenvwrapper。 pip install virtualenvwrapper-win 接着&#xff0c;添加环境变量。 echo %WORKON_HOME% 接下来就是创建虚拟环境&#xff0c;假如创建myenv mkvirtualenv myenv 进入…

sqllab第二十八关通关笔记(附带28a)

知识点&#xff1a; union select 整体过滤 union all select 替换where id(输入)空格 过滤了&#xff0c;使用%09代替 经过不断的测试&#xff0c;发现原始语句为 where id(输入) 构造payload:id1)and%091(1 成功回显出了相关的信息 好&#xff0c;尝试进行错误注入 构造…

acwing 3302. 表达式求值

​​​​​​给定一个表达式&#xff0c;其中运算符仅包含 ,-,*,/&#xff08;加 减 乘 整除&#xff09;&#xff0c;可能包含括号&#xff0c;请你求出表达式的最终值。 注意&#xff1a; 数据保证给定的表达式合法。题目保证符号 - 只作为减号出现&#xff0c;不会作为负号…