我正在使用 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