0

0

使用 Go 通过自定义 io.Reader 确定性生成 RSA 私钥

WBOY

WBOY

发布时间:2024-02-09 14:12:10

|

481人浏览过

|

来源于stackoverflow

转载

使用 go 通过自定义 io.reader 确定性生成 rsa 私钥

php小编百草将为大家介绍如何使用Go语言通过自定义io.Reader接口来确定性生成RSA私钥。RSA是一种非对称加密算法,常用于数据加密和数字签名。在生成RSA私钥时,通常需要从随机源获取随机数,但有时候我们需要根据特定的规则生成确定性的私钥。本文将详细讲解如何实现自定义的io.Reader接口,并使用该接口生成确定性的RSA私钥。通过阅读本文,您将掌握这一有用的技巧,为您的加密应用提供更多灵活性和可控性。

问题内容

出于可能最好不回答的原因,我需要生成无限的 rsa 公钥/私钥。请注意,这没有用于任何高度安全的事情,所以请不要告诉我不要这样做,是的,我知道它并不理想。我所说的“无限”是指我需要其中未知数量(数十亿到数万亿),并且在使用之前创建它们是不可能的。

由于这会消耗无限的空间并需要无限的时间来生成,因此我需要在运行时执行此操作。

但是,对于给定的输入,我还需要具有相同的密钥对。这意味着我需要根据输入确定性地重新创建 rsa 密钥。

我使用 go,通常您使用以下命令创建密钥,

k, err := rsa.generatekey(rand.reader, 2048)

当然,问题是 rand.reader 是由 crypto/rand 提供的,因此无法为其提供种子。

我认为可以提供我自己的阅读器实现来实现我的目标。我查看了 generatekey 的源代码,注意到它正在寻找素数,因此我实现了自己的阅读器,这样我就可以控制返回的“随机”素数,从而允许我在需要时生成相同的密钥,

type reader struct {
    data   []byte
    sum    int
    primes []int
}

func newreader(toread string) *reader {
    primes := sieveoferatosthenes(10_000_000)
    return &reader{[]byte(toread), 0, primes}
}

func (r *reader) read(p []byte) (n int, err error) {
    r.sum = r.sum + 1

    if r.sum >= 100_000 {
        return r.primes[rand.intn(len(r.primes))], io.eof
    }

    return r.primes[rand.intn(len(r.primes))], nil
}

func sieveoferatosthenes(n int) (primes []int) {
    b := make([]bool, n)
    for i := 2; i < n; i++ {
        if b[i] == true {
            continue
        }
        primes = append(primes, i)
        for k := i * i; k < n; k += i {
            b[k] = true
        }
    }
    return
}

然后我可以像这样调用生成密钥

k, err := rsa.GenerateKey(NewReader(""), 2048)

它可以编译,但由于零指针而在运行时崩溃。我对 go 相当满意,但 rsa 的实现超出了我的理解。寻找更好的方法来实现这一目标,或者寻找我需要做的事情来让我的读者工作。

皮卡智能
皮卡智能

AI驱动高效视觉设计平台

下载

请注意,我在这里唯一的硬性要求是能够为给定的输入生成相同的密钥,并使用 rsa.generatekey 或兼容替换。输入实际上可以是任何东西,只要我得到与输出相同的密钥即可。

这是一个 go playground 链接,展示了我目前所在的位置 https://go.dev/play/p/jd1naopr5ad

解决方法

read 方法未执行预期操作。它不会用随机字节填充输入 p 字节切片。如果您查看 crypto/rand.read 方法的 unix 实现,它将输入字节切片传递给另一个读取器。所以基本上你需要用随机数填充字节片。例如:

func (r *reader) read(p []byte) (n int, err error) {
        i := 0
        b := p

        for i < len(b) {
                if len(b) < 4 {
                        b[0] = 7
                        b = b[1:]
                } else {
                        binary.littleendian.putuint32(b, uint32(rand.intn(len(r.primes))))
                        b = b[4:]
                }
        }

        return len(p), nil
}

这是游乐场的链接

更新

正如 erwin 在回答中提到的,有一个名为 crypto/rand.read 的函数,它有 50% 的机会从 rand 读取器读取 1 个字节,从而使该函数具有不确定性。但是您可以通过在 read 方法中添加 if 语句来解决:如果输入切片的长度为 1,则忽略所有内容并返回。否则,向输入切片提供素数:

func (r *Reader) Read(p []byte) (n int, err error) {
    i := 0
    b := p

    if len(p) == 1 {
        println("maybeReadRand")
        return 1, nil
    }

    for i < len(b) {
        if len(b) < 4 {
            b[0] = 7
            b = b[1:]
        } else {
            binary.LittleEndian.PutUint32(b, uint32(r.primes[r.i]))
            r.i++
            b = b[4:]
        }
    }

    return len(p), nil
}

在此片段中,我创建了 2 个密钥,并且它们都是相等的。 p>

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2914

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1738

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1568

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

1120

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1566

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1297

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1689

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1310

2023.11.13

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

2

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 4.9万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

Go 教程
Go 教程

共32课时 | 4.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号