Menjana kunci persendirian RSA secara pasti dengan io.Reader tersuai menggunakan Go

WBOY
Lepaskan: 2024-02-09 14:12:10
ke hadapan
371 orang telah melayarinya

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

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.

Kandungan soalan

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)
Salin selepas log masuk

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
}
Salin selepas log masuk

Lepas tu boleh panggil generate key macam ni

k, err := rsa.GenerateKey(NewReader(""), 2048)
Salin selepas log masuk

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

Penyelesaian

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!