RSACryptoServiceProvider,.NET / PowerShell Core中的SignData和填充

时间:2018-05-04 05:28:55

标签: .net powershell cryptography

我试图使用Powershell的.NET RSACryptoServiceProvider类的SignData方法。

在Windows 10 / Powershell 5.1 / .NET 4.7上,以下代码可靠地运行:

$toSign = [System.Text.Encoding]::UTF8.GetBytes("ABCDE")

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.import("c:\ps\GAdmin\apiaccess.pfx","notasecret","Exportable,PersistKeySet")
$cert | fl *

$params = New-Object System.Security.Cryptography.CspParameters
$params.KeyContainerName = $cert.PrivateKey.CspKeyContainerInfo.KeyContainerName
$params.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider"
$params
$cert.PrivateKey.CspKeyContainerInfo.KeyNumber
$params.KeyNumber = 1
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider($params)
$tosign
$rsa.SignData($toSign,"SHA256")

但是,在使用.NET Core / Powershell Core的Linux(或Windows)上,我遇到了问题。我可以实例化一个RSACryptoServiceProvider,但SignData错误输出:

$cert = Get-PfxCertificate ./apiaccess.pfx -Password (ConvertTo-SecureString "notasecret" -AsPlainText -Force)
$rsa = $cert.PrivateKey
$rsa.SignData($toSign,"SHA256")
  

无法找到" SignData"和参数计数:" 2"。   在行:1个字符:1   + $ rsa.SignData($ toSign," SHA256")   + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   + CategoryInfo:NotSpecified:(:) [],MethodException   + FullyQualifiedErrorId:MethodCountCouldNotFindBest

检查方法定义 - 似乎需要填充参数:

($rsa | get-member SignData).Definition
  

byte [] SignData(byte [] data,System.Security.Cryptography.HashAlgorithmName hashAlgorithm,System.Security.Cryptography.RSASignaturePadding padding),byte [] SignData(byte [] data,int offset,int count,System。 Security.Cryptography.HashAlgorithmName hashAlgorithm,System.Security.Cryptography.RSASignaturePadding padding),byte [] SignData(System.IO.Stream data,System.Security.Cryptography.HashAlgorithmName hashAlgorithm,System.Security.Cryptography.RSASignaturePadding padding)

所以我的问题是:如何指定填充并从Powershell Core调用SignData?

1 个答案:

答案 0 :(得分:2)

$cert.PrivateKey可能返回RSACryptoServiceProvider以外的内容。你真的应该避免调用那个属性,并且应该用$cert.GetRSAPrivateKey()替换它(或者你期望密钥的任何算法......如果你弄错了它会返回null所以异常不是一个问题)。并不是说它会有所帮助,除了它保证永远不会在Linux上返回RSACryptoServiceProvider(并且“几乎保证”不会在Windows上返回它)。虽然它解决你在Windows上重新解释CSP参数的需要。

而不是叫'

$rsa.SignData($toSign, "SHA256")

你应该致电

$rsa.SignData(
    $toSign,
    System.Security.Cryptography.HashAlgorithmNames.SHA256,
    System.Security.Cryptography.RSASignaturePadding.Pkcs1)

我实际上并不知道后两个参数的powershell-ese,希望我对该语言语法的理解足以解锁你。这里的“SHA256”和“Pkcs1”都是属性,所以如果它让你的代码更漂亮,你可以将它们保存到本地。