editor php Baicao akan memperkenalkan cara menggunakan bahasa Go untuk menjana kunci peribadi RSA secara deterministik melalui antara muka io.Reader tersuai. RSA ialah algoritma penyulitan asimetri yang biasa digunakan untuk penyulitan data dan tandatangan digital. Apabila menjana kunci persendirian RSA, kita biasanya perlu mendapatkan nombor rawak daripada sumber rawak, tetapi kadangkala kita perlu menjana kunci persendirian yang menentukan mengikut peraturan tertentu. Artikel ini akan menerangkan secara terperinci cara melaksanakan antara muka io.Reader tersuai dan menggunakan antara muka ini untuk menjana kunci persendirian RSA yang menentukan. Dengan membaca artikel ini, anda akan mempelajari teknik berguna ini untuk memberikan aplikasi kriptografi anda lebih fleksibiliti dan kawalan.
Atas sebab yang mungkin tidak dijawab, saya perlu menjana kunci awam/peribadi rsa tanpa had. Ambil perhatian bahawa ini tidak digunakan untuk apa-apa perkara yang sangat selamat, jadi tolong jangan beritahu saya untuk tidak melakukannya, dan ya saya tahu ia tidak sesuai. Apa yang saya maksudkan dengan "tak terhingga" ialah saya memerlukan nombor yang tidak diketahui (berbilion hingga trilion), dan menciptanya sebelum menggunakannya adalah mustahil.
Memandangkan ini menggunakan ruang yang tidak terhingga dan mengambil masa yang tidak terhingga untuk menjana, saya perlu melakukan ini pada masa jalanan.
Namun, saya juga perlu mempunyai pasangan kunci yang sama untuk input yang diberikan. Ini bermakna saya perlu mencipta semula kunci rsa secara deterministik berdasarkan input.
Saya menggunakan go, biasanya anda menggunakan arahan berikut untuk mencipta kunci,
k, err := rsa.generatekey(rand.reader, 2048)
Sudah tentu masalahnya ialah rand.reader
是由 crypto/rand
disediakan, jadi ia tidak boleh disemai.
Saya fikir adalah mungkin untuk menyediakan pelaksanaan pembaca saya sendiri untuk mencapai matlamat saya. Saya melihat kod sumber generatekey
dan mendapati ia sedang mencari nombor perdana, jadi saya melaksanakan pembaca saya sendiri supaya saya boleh mengawal nombor perdana "rawak" yang dikembalikan, membolehkan saya menjana kunci yang sama jika perlu,
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 }
Lepas tu boleh panggil generate key macam ni
k, err := rsa.GenerateKey(NewReader(""), 2048)
Ia menyusun tetapi ranap pada masa jalan kerana penunjuk sifar. Saya cukup gembira dengan go, tetapi pelaksanaan rsa di luar pemahaman saya. Mencari cara yang lebih baik untuk mencapai ini, atau mencari perkara yang perlu saya lakukan untuk menjadikannya berkesan untuk pembaca saya.
Perhatikan bahawa satu-satunya keperluan sukar saya di sini ialah dapat menjana kunci yang sama untuk input yang diberikan, menggunakan rsa.generatekey
atau penggantian yang serasi. Input boleh menjadi apa-apa sahaja selagi saya mendapat kunci yang sama dengan output.
Berikut ialah pautan go playground yang menunjukkan kedudukan saya sekarang di https://go.dev/play/p/jd1naopr5ad
read
方法未执行预期操作。它不会用随机字节填充输入 p
字节切片。如果您查看 crypto/rand.read
Pelaksanaan unix bagi kaedah yang menghantar sepotong bait input kepada pembaca lain. Jadi pada asasnya anda perlu mengisi kepingan bait dengan nombor rawak. Contohnya:
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 }
Ini ialah pautan ke taman permainan.
Kemas kini
Seperti yang erwin sebutkan dalam jawapannya, terdapat fungsi yang dipanggil maybereadrand
yang mempunyai peluang 50% untuk membaca 1 bait daripada pembaca rand, menjadikan fungsi itu tidak menentukan. Tetapi anda boleh menyelesaikannya dengan menambah pernyataan if dalam kaedah baca: jika panjang kepingan input ialah 1, abaikan semuanya dan kembali. Jika tidak, berikan nombor perdana pada kepingan input:
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 }
Dalam snippet ini, saya mencipta 2 kekunci dan kedua-duanya adalah sama. p>
Atas ialah kandungan terperinci Menjana kunci persendirian RSA secara pasti dengan io.Reader tersuai menggunakan Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!