powershell 如何通过密码提供程序生成一个大素数?

frebpwbc  于 2023-02-19  发布在  Shell
关注(0)|答案(1)|浏览(145)

我想通过Powershell中的内置加密提供程序生成一个2048位的质数。这是我目前拥有的代码,但是通过Rabin-Miller测试的结果告诉我,这个数字不是质数。这里出了什么问题?

$rsa = [System.Security.Cryptography.RSA]::Create(2048)
$format = [System.Security.Cryptography.CngKeyBlobFormat]::GenericPrivateBlob
$bytes = $rsa.Key.Export($format)

[bigint]$prime = 0
foreach($b in $bytes) {$prime = ($prime -shl 8) + $b}
$prime

这个链接告诉我,BLOB应该包含两个RSA素数,但由于任何原因,我无法获得预期的信息:https://learn.microsoft.com/en-us/windows/win32/seccrypto/rsa-schannel-key-blobs#private-key-blobs

m1m5dgzv

m1m5dgzv1#

最后,我在更深入地研究了通用BLOB格式之后解决了这个问题。这里的学习点是这样一个事实,即4096 RSA密钥包括两个2048位素数。一个在BLOB的最后256字节上,另一个素数在其前面的256字节中。
下面是工作代码:

# generating two random 2048-bit PRIME numbers:

cls
$rsa = [System.Security.Cryptography.RSA]::Create(4096)
$key = $rsa.Key.Export('PRIVATEBLOB')
$len = $key.Length

$Pb = [byte[]]::new(256+1)
[array]::Copy($key, $len-512, $Pb, 1, 256)
[array]::Reverse($Pb)
$P = [bigint]$Pb
write-host $P

# optionally same for the second prime in the BLOB:
$Qb = [byte[]]::new(256+1)
[array]::Copy($key, $len-256, $Qb, 1, 256)
[array]::Reverse($Qb)
$Q = [bigint]$Qb
write-host $Q

# optionally here the Test-Function:
function Is-PrimeRabinMiller ([BigInt] $Source, [int] $Iterate)  {
    if ($source -eq 2 -or $source -eq 3) {return $true}
    if (($source -band 1) -eq 0) {return $false}

    [BigInt]$d = $source - 1;
    $s = 0;
    while (($d -band 1) -eq 0) {$d = $d -shr 1; $s++;}

    if ($source.ToByteArray().Length -gt 255) {
        $sourceLength = 255
    }
    else {
        $sourceLength = $source.ToByteArray().Length
    }

    $rngProv = [System.Security.Cryptography.RNGCryptoServiceProvider]::Create()
    [Byte[]] $bytes = $sourceLength 

    [BigInt]$a = 0
    foreach ($i in 1..$iterate) {          
        do {
            $rngProv.GetBytes($bytes)
            $a = [BigInt]$bytes            
        } while (($a -lt 2) -or ($a -ge ($source - 2)))                              
     
        [BigInt]$x = ([BigInt]::ModPow($a,$d,$source))
        if ($x -eq 1 -or ($x -eq $source-1)) {continue}

        foreach ($j in 1..($s-1)) {            
            $x = [BigInt]::ModPow($x, 2, $source)
            if ($x -eq 1) {return $false}
            if ($x -eq $source-1) {break}
        }
        return $false
    }
    return $true
}

if (Is-PrimeRabinMiller $P 42) {"P is prime!"}
if (Is-PrimeRabinMiller $Q 42) {"Q is prime!"}

此外,我创建了一个小函数的基础上,上述发现,产生一个随机大素数:

function get-RandomPrime {
    Param (
        [parameter(Mandatory=$true)]
        [ValidateRange(256, 8192)]
        [ValidateScript({$_ % 8 -eq 0})]
        [int]$bitLength
    )
    $rsa = [System.Security.Cryptography.RSA]::Create($bitLength*2)
    $key = $rsa.Key.Export('PRIVATEBLOB')
    $len = $key.Length

    $byteLength = [int]$bitLength/8
    $bytes = [byte[]]::new($byteLength+1)
    [array]::Copy($key, $len-$byteLength, $bytes, 1, $byteLength)
    [array]::Reverse($bytes)
    [bigint]$bytes
}
$prime = get-RandomPrime -bitLength 2048
write-host "`nprime (DEC):" $prime
write-host "`nprime (HEX):" $prime.ToString('X2').SubString(1)

相关问题