我如何注册使用RSA和SHA256与.NET的文件? [英] How can I sign a file using RSA and SHA256 with .NET?

查看:320
本文介绍了我如何注册使用RSA和SHA256与.NET的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序将耗时一组文件和签字。 (我不是要装配签署。)有一个.p12文件,我得到的私钥。

My application will take a set of files and sign them. (I'm not trying to sign an assembly.) There is a .p12 file that I get the private key from.

这是在code我试图用,但我得到一个 System.Security.Cryptography.CryptographicException指定了无效的算法。

This is the code I was trying to use, but I get a System.Security.Cryptography.CryptographicException "Invalid algorithm specified.".

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);

根据该<一href="http://stackoverflow.com/questions/7433074/why-am-i-getting-invalid-algorithm-specified-exception/7433202#7433202">answer它不能这样做(在的RSACryptoServiceProvider不支持SHA-256),但我希望它可能使用不同的库,就像充气城堡是可能的。

According to this answer it can't be done (the RSACryptoServiceProvider does not support SHA-256), but I was hoping that it might be possible using a different library, like Bouncy Castle.

我是新来的这些东西,我发现充气城堡是非常混乱。我移植一个Java应用到C#,我必须使用相同类型的加密签署的文件,所以我坚持RSA + SHA256。

I'm new to this stuff and I'm finding Bouncy Castle to be very confusing. I'm porting a Java app to C# and I have to use the same type of encryption to sign the files, so I am stuck with RSA + SHA256.

我怎样才能做到这一点使用充气城堡,OpenSSL.NET,Security.Cryptography,或者我还没有听说过的另一个第三方库?我假设,如果它可以用Java做的话,就可以在C#来完成。

How can I do this using Bouncy Castle, OpenSSL.NET, Security.Cryptography, or another 3rd party library I haven't heard of? I'm assuming, if it can be done in Java then it can be done in C#.

更新:

这是我从链接中poupou的anwser了

this is what I got from the link in poupou's anwser

        X509Certificate2 cert = new X509Certificate2(KeyStoreFile, password");
        RSACryptoServiceProvider rsacsp = (RSACryptoServiceProvider)cert.PrivateKey;
        CspParameters cspParam = new CspParameters();
        cspParam.KeyContainerName = rsacsp.CspKeyContainerInfo.KeyContainerName;
        cspParam.KeyNumber = rsaCSP.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2;
        RSACryptoServiceProvider aescsp = new RSACryptoServiceProvider(cspParam);
        aescsp.PersistKeyInCsp = false;
        byte[] signed = aescsp.SignData(File.ReadAllBytes(file), "SHA256");
        bool isValid = aescsp.VerifyData(File.ReadAllBytes(file), "SHA256", signed);

问题是,我没有得到相同的结果,因为我与原来的工具了。据我可以告诉读取c表示不实际的签名是不使用从密钥存储文件中的PrivateKey的CryptoServiceProvider的$ C $。这是否正确?

The problem is that I'm not getting the same results as I got with the original tool. As far as I can tell from reading the code the CryptoServiceProvider that does the actual signing is not using the PrivateKey from key store file. Is that Correct?

推荐答案

RSA + SHA256可以和将工作...

RSA + SHA256 can and will work...

您后面的例子的可以的不工作的时候,它应该使用哈希算法的OID,而不是它的名字。按照您的第一个例子,这是从一个调用[CryptoConfig.MapNameToOID](AlgorithmName)获得<一href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptoconfig.mapnametooid.aspx"相对=nofollow> 1 其中,AlgorithmName是你所提供的(即SHA256)。

Your later example may not work all the time, it should use the hash algorithm's OID, rather than it's name. As per your first example, this is obtained from a call to [CryptoConfig.MapNameToOID](AlgorithmName)1 where AlgorithmName is what you are providing (i.e. "SHA256").

首先,你将需要与私钥证书。我通常读矿从LOCALMACHINE或的currentUser店使用公共密钥文件(.CER)来识别私钥,然后枚举哈希证书和匹配...

First you are going to need is the certificate with the private key. I normally read mine from the LocalMachine or CurrentUser store by using a public key file (.cer) to identify the private key, and then enumerate the certificates and match on the hash...

X509Certificate2 publicCert = new X509Certificate2(@"C:\mycertificate.cer");

//Fetch private key from the local machine store
X509Certificate2 privateCert = null;
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach( X509Certificate2 cert in store.Certificates)
{
    if (cert.GetCertHashString() == publicCert.GetCertHashString())
        privateCert = cert;
}

但是你到了那里,一旦你得到的,我们都需要重建它私钥证书。这可能是由于需要的方式证书创建它的私钥,但我真的不知道为什么。不管怎样,我们这样做,首先导出密钥,然后再重新导入它使用任何中间格式你喜欢的,最简单的就是XML:

However you get there, once you've obtained a certificate with a private key we need to reconstruct it. This may be required due to the way the certificate creates it's private key, but I'm not really sure why. Anyway, we do this by first exporting the key and then re-importing it using whatever intermediate format you like, the easiest is xml:

//Round-trip the key to XML and back, there might be a better way but this works
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));

在做到这一点,我们现在可以按如下签字一块数据:

Once that is done we can now sign a piece of data as follows:

//Create some data to sign
byte[] data = new byte[1024];

//Sign the data
byte[] sig = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));

最后,验证,可直接与该证书的公钥进行,而不需要重建,因为我们用私钥所做的:

Lastly, the verification can be done directly with the certificate's public key without need for the reconstruction as we did with the private key:

key = (RSACryptoServiceProvider)publicCert.PublicKey.Key;
if (!key.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), sig))
    throw new CryptographicException();

这篇关于我如何注册使用RSA和SHA256与.NET的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆