0

我正在使用 bouncycastle 1.8.8。我正在尝试计算 RAW 签名并将其导出到文件中。导出 RAW 签名后,我尝试将其导入并验证导入的 RAW 签名。导入 RAW 签名并验证后,我有时会得到 $true,有时会得到 $false ......你能告诉我我应该如何将 RAW 签名导出到文件中,然后导入并验证它吗?

那是我的代码:

Add-Type -Path "..\Lib\BouncyCastle.dll"
$ProjectPath = (gi '..\').FullName

function ComputeHash {
    param (
        [parameter(Mandatory=$true)][System.String] $Path
    )

    [void]([byte[]] $DataFileRawBytes = (gci -Path $Path | % {[System.IO.File]::ReadAllBytes($_.FullName)}) -as [byte[]]);
    [void]([Org.BouncyCastle.Crypto.Digests.Gost3411_2012_256Digest] $Gost3411_2012_256Digest = [Org.BouncyCastle.Crypto.Digests.Gost3411_2012_256Digest]::new());
    [void]([byte[]] $HashCode = [byte[]]::new(32));
    [void]($Gost3411_2012_256Digest.BlockUpdate($DataFileRawBytes, 0, $DataFileRawBytes.Length));
    [void]($Gost3411_2012_256Digest.DoFinal($HashCode, 0));
    [void]($Gost3411_2012_256Digest.Reset());
    return $HashCode;
}

function Write-Keys {
    param (
        [parameter(Mandatory=$true)] $KeyPair,
        [parameter(Mandatory=$true)][System.String] $Path,
        [parameter(Mandatory=$true)][System.String] $KeyVis
    )
    if ($KeyVis -eq "prk") {
        [System.IO.TextWriter] $tw = [System.IO.File]::CreateText($Path + "\prk.pem");
    }
    elseif ($KeyVis -eq "pbk") {
        [System.IO.TextWriter] $tw = [System.IO.File]::CreateText($Path + "\pbk.pem");
    }
    $pw = [Org.BouncyCastle.OpenSsl.PemWriter]::new($tw);
    $pw.WriteObject($KeyPair);
    $tw.Flush();
    $tw.Close();
    $tw.Dispose();
}

function Read-Keys {
    param (
        [parameter(Mandatory=$true)][System.String] $Path,
        [parameter(Mandatory=$true)][System.String] $KeyVis
    )
    if ($KeyVis -eq "prk") {
        [System.IO.TextReader] $tr = [System.IO.File]::OpenText($Path + "\prk.pem")
    }
    elseif ($KeyVis -eq "pbk") {
        [System.IO.TextReader] $tr = [System.IO.File]::OpenText($Path + "\pbk.pem")
    }
    $pr = [Org.BouncyCastle.OpenSsl.PemReader]::new($tr);
    $KeyPair = $pr.ReadObject();
    $tr.Close();
    $tr.Dispose();
    return $KeyPair
}

function Write-Signature {
    param (
        [parameter(Mandatory=$true)] $Signature,
        [parameter(Mandatory=$true)][System.String] $Path
    )
    [System.IO.File]::WriteAllBytes($Path + "\signature.pem", ($Signature[0].ToByteArrayUnsigned() + $Signature[1].ToByteArrayUnsigned()))

}

function Read-Signature {
    param (
        [parameter(Mandatory=$true)][System.String] $Path
    )
    
    $Full = [System.IO.File]::ReadAllBytes($Path + "\signature.pem");
    $Signature = [Org.BouncyCastle.Math.BigInteger]::new($Full[0..31] -as [byte[]]), [Org.BouncyCastle.Math.BigInteger]::new($Full[32..63] -as [byte[]])
    return $Signature;
}

function Test-Export-Keys-And-Signature {
    param (
        [parameter(Mandatory=$false)][System.Int16] $KeyLength = 512,
        [parameter(Mandatory=$false)][System.String] $Path
    )

    [byte[]] $HashCode = ComputeHash -Path ($Path + "\to_be_signed\to_be_signed.txt");
    $secureRandom = [Org.BouncyCastle.Security.SecureRandom]::new();
    $curve = [Org.BouncyCastle.Asn1.CryptoPro.ECGost3410NamedCurves]::GetByName("GostR3410-2001-CryptoPro-A")
    $dp = [Org.BouncyCastle.Crypto.Parameters.ECDomainParameters]::new($curve.curve, $curve.g, $curve.n, $curve.h, $curve.GetSeed())
    $ECGost3410Parameters = [Org.BouncyCastle.Crypto.Parameters.ECGost3410Parameters]::new($dp, "1.2.643.2.2.36.0", "1.2.643.7.1.1.2.2", $null)
    $ECKeyGenerationParameters = [Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters]::new($ECGost3410Parameters, $secureRandom);
    $generator = [Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator]::new();
    $generator.Init($ECKeyGenerationParameters);
    $KeyPair = $generator.GenerateKeyPair();
    
    [Org.BouncyCastle.Crypto.Signers.ECGost3410Signer] $ECGost3410Signer = [Org.BouncyCastle.Crypto.Signers.ECGost3410Signer]::new();
    $ParametersWithRandom = [Org.BouncyCastle.Crypto.Parameters.ParametersWithRandom]::new($KeyPair.Private, $secureRandom);
    $ECGost3410Signer.Init($true, $ParametersWithRandom);

    $Signature = $ECGost3410Signer.GenerateSignature($HashCode); #Compute RAW-signature    
    Write-Signature -Signature $Signature -Path ($Path + "\sig"); #Export RAW-signature
    $Signature_2 = Read-Signature -Path ($Path + "\sig"); #Import RAW-signature
    $ECGost3410Signer.Init($false, $KeyPair.Public);
    $ECGost3410Signer.VerifySignature($HashCode, $Signature_2[0], $Signature_2[1]); #Verify imported RAW-signature: sometimes get $true, sometimes get $false 

    Write-Keys -KeyPair $KeyPair.Private -Path ($Path + "\keys") -KeyVis "prk" #Export private key
    Write-Keys -KeyPair $KeyPair.Public -Path ($Path + "\keys") -KeyVis "pbk" #Export public key

    $Pbk = Read-Keys -Path ($Path + "\keys") -KeyVis "pbk" #Import public key
    $Prk = Read-Keys -Path ($Path + "\keys") -KeyVis "prk" #Import private key
    $ParametersWithRandom = [Org.BouncyCastle.Crypto.Parameters.ParametersWithRandom]::new($Prk, $secureRandom);
    $ECGost3410Signer.Init($true, $ParametersWithRandom);
    $Signature = $ECGost3410Signer.GenerateSignature($HashCode);
    $ECGost3410Signer.Init($false, $Pbk);
    $ECGost3410Signer.VerifySignature($HashCode, $Signature[0], $Signature[1]); #Verify non-exported RAW-signature with imported public key. Always get $true
}

Test-Export-Keys-And-Signature -Path $ProjectPath
4

0 回答 0