使用 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 的實現超出了我的理解。尋找更好的方法來實現這一目標,或尋找我需要做的事情來讓我的讀者工作。
請注意,我在這裡唯一的硬性要求是能夠為給定的輸入產生相同的金鑰,並使用 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 在回答中提到的,有一個名為
maybereadrand 的函數,它有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 }
以上是使用 Go 透過自訂 io.Reader 確定性產生 RSA 私鑰的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

Go語言中字符串打印的區別:使用Println與string()函數的效果差異在Go...

Go語言中結構體定義的兩種方式:var與type關鍵字的差異Go語言在定義結構體時,經常會看到兩種不同的寫法:一�...

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...
