X509Certificate2 with Private Key signing data using SHA256withRSA
This is a bit related to the answer to X509Certificate2 from store with private key.
It seems that when I want to use SHA256withRSA I can't use service provider directly from the certificate's PrivateKey - I need to create new crypto service provider:
var bytes = new byte { 0, 1, 2, 3 };
//_cert - X509Certificate2 with private key
//csp1 is of type I need, but it won't work
var csp1 = _cert.PrivateKey as RSACryptoServiceProvider;
var cspParameters = new CspParameters
{
KeyContainerName = csp1.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp1.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
var csp2 = new RSACryptoServiceProvider(cspParameters);
//I can't use csp1 here - will throw "CryptographicException : Invalid algorithm specified."
//I can use csp1 with "SHA1" though
var signature = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
I've found some information about this here:
https://blogs.msdn.microsoft.com/shawnfa/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures/
But the above solution is taken from comments section and I don't really understand why I need to jump through hoops to use one of the common algorithms. So what I want to ask is:
- Why
csp1
does not work with SHA256 exactly? - Is it correct to create the
csp2
like I did? - Is there a better/newer way I can do it in .NET?
If needed the cert with private key can be generated as follows:
openssl req -x509 -sha256 -newkey rsa:2048 -keyout ./temp/key.key -out ./temp/crt.crt -days 10 –nodes
openssl pkcs12 -export -out .tempcert.pfx -inkey .tempkey.key –in .tempcrt.crt
c# .net cryptography
add a comment |
This is a bit related to the answer to X509Certificate2 from store with private key.
It seems that when I want to use SHA256withRSA I can't use service provider directly from the certificate's PrivateKey - I need to create new crypto service provider:
var bytes = new byte { 0, 1, 2, 3 };
//_cert - X509Certificate2 with private key
//csp1 is of type I need, but it won't work
var csp1 = _cert.PrivateKey as RSACryptoServiceProvider;
var cspParameters = new CspParameters
{
KeyContainerName = csp1.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp1.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
var csp2 = new RSACryptoServiceProvider(cspParameters);
//I can't use csp1 here - will throw "CryptographicException : Invalid algorithm specified."
//I can use csp1 with "SHA1" though
var signature = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
I've found some information about this here:
https://blogs.msdn.microsoft.com/shawnfa/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures/
But the above solution is taken from comments section and I don't really understand why I need to jump through hoops to use one of the common algorithms. So what I want to ask is:
- Why
csp1
does not work with SHA256 exactly? - Is it correct to create the
csp2
like I did? - Is there a better/newer way I can do it in .NET?
If needed the cert with private key can be generated as follows:
openssl req -x509 -sha256 -newkey rsa:2048 -keyout ./temp/key.key -out ./temp/crt.crt -days 10 –nodes
openssl pkcs12 -export -out .tempcert.pfx -inkey .tempkey.key –in .tempcrt.crt
c# .net cryptography
add a comment |
This is a bit related to the answer to X509Certificate2 from store with private key.
It seems that when I want to use SHA256withRSA I can't use service provider directly from the certificate's PrivateKey - I need to create new crypto service provider:
var bytes = new byte { 0, 1, 2, 3 };
//_cert - X509Certificate2 with private key
//csp1 is of type I need, but it won't work
var csp1 = _cert.PrivateKey as RSACryptoServiceProvider;
var cspParameters = new CspParameters
{
KeyContainerName = csp1.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp1.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
var csp2 = new RSACryptoServiceProvider(cspParameters);
//I can't use csp1 here - will throw "CryptographicException : Invalid algorithm specified."
//I can use csp1 with "SHA1" though
var signature = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
I've found some information about this here:
https://blogs.msdn.microsoft.com/shawnfa/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures/
But the above solution is taken from comments section and I don't really understand why I need to jump through hoops to use one of the common algorithms. So what I want to ask is:
- Why
csp1
does not work with SHA256 exactly? - Is it correct to create the
csp2
like I did? - Is there a better/newer way I can do it in .NET?
If needed the cert with private key can be generated as follows:
openssl req -x509 -sha256 -newkey rsa:2048 -keyout ./temp/key.key -out ./temp/crt.crt -days 10 –nodes
openssl pkcs12 -export -out .tempcert.pfx -inkey .tempkey.key –in .tempcrt.crt
c# .net cryptography
This is a bit related to the answer to X509Certificate2 from store with private key.
It seems that when I want to use SHA256withRSA I can't use service provider directly from the certificate's PrivateKey - I need to create new crypto service provider:
var bytes = new byte { 0, 1, 2, 3 };
//_cert - X509Certificate2 with private key
//csp1 is of type I need, but it won't work
var csp1 = _cert.PrivateKey as RSACryptoServiceProvider;
var cspParameters = new CspParameters
{
KeyContainerName = csp1.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp1.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
var csp2 = new RSACryptoServiceProvider(cspParameters);
//I can't use csp1 here - will throw "CryptographicException : Invalid algorithm specified."
//I can use csp1 with "SHA1" though
var signature = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
I've found some information about this here:
https://blogs.msdn.microsoft.com/shawnfa/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures/
But the above solution is taken from comments section and I don't really understand why I need to jump through hoops to use one of the common algorithms. So what I want to ask is:
- Why
csp1
does not work with SHA256 exactly? - Is it correct to create the
csp2
like I did? - Is there a better/newer way I can do it in .NET?
If needed the cert with private key can be generated as follows:
openssl req -x509 -sha256 -newkey rsa:2048 -keyout ./temp/key.key -out ./temp/crt.crt -days 10 –nodes
openssl pkcs12 -export -out .tempcert.pfx -inkey .tempkey.key –in .tempcrt.crt
c# .net cryptography
c# .net cryptography
asked Nov 23 '18 at 15:12
DevNewbDevNewb
741617
741617
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It all depends on where your certificate is coming from. Like the MSDN comment says, if it's coming from Microsoft Base Cryptographic Provider, then it will not work with SHA256. This CSP came out with the first version of CryptoAPI back in 1996, and does not understand SHA256 because SHA256 was not around back then.
The way to check and handle this gracefully would be:
public byte SignData(RSACryptoServiceProvider csp, byte bytes)
{
byte sig = null;
if ((csp.CspKeyContainerInfo.ProviderType == PROV_RSA_FULL || csp.CspKeyContainerInfo.ProviderType == PROV_RSA_SCHANNEL) && !csp.CspKeyContainerInfo.HardwareDevice)
{
var cspParameters = new CspParameters
{
KeyContainerName = csp.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
using (var csp2 = new RSACryptoServiceProvider(cspParameters))
{
sig = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
}
else {
sig = csp.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
return sig;
}
FYI the CryptoAPI is being deprecated in favor of Cryptography API: Next Generation. One way to do what you want with CNG in C# would be with System.Security.Cryptography.Cng:
...
using (RSA rsa = new RSACng())
{
byte signature = rsa.SignData(message, hashAlgorithm, paddingMode);
...
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449086%2fx509certificate2-with-private-key-signing-data-using-sha256withrsa%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It all depends on where your certificate is coming from. Like the MSDN comment says, if it's coming from Microsoft Base Cryptographic Provider, then it will not work with SHA256. This CSP came out with the first version of CryptoAPI back in 1996, and does not understand SHA256 because SHA256 was not around back then.
The way to check and handle this gracefully would be:
public byte SignData(RSACryptoServiceProvider csp, byte bytes)
{
byte sig = null;
if ((csp.CspKeyContainerInfo.ProviderType == PROV_RSA_FULL || csp.CspKeyContainerInfo.ProviderType == PROV_RSA_SCHANNEL) && !csp.CspKeyContainerInfo.HardwareDevice)
{
var cspParameters = new CspParameters
{
KeyContainerName = csp.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
using (var csp2 = new RSACryptoServiceProvider(cspParameters))
{
sig = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
}
else {
sig = csp.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
return sig;
}
FYI the CryptoAPI is being deprecated in favor of Cryptography API: Next Generation. One way to do what you want with CNG in C# would be with System.Security.Cryptography.Cng:
...
using (RSA rsa = new RSACng())
{
byte signature = rsa.SignData(message, hashAlgorithm, paddingMode);
...
}
add a comment |
It all depends on where your certificate is coming from. Like the MSDN comment says, if it's coming from Microsoft Base Cryptographic Provider, then it will not work with SHA256. This CSP came out with the first version of CryptoAPI back in 1996, and does not understand SHA256 because SHA256 was not around back then.
The way to check and handle this gracefully would be:
public byte SignData(RSACryptoServiceProvider csp, byte bytes)
{
byte sig = null;
if ((csp.CspKeyContainerInfo.ProviderType == PROV_RSA_FULL || csp.CspKeyContainerInfo.ProviderType == PROV_RSA_SCHANNEL) && !csp.CspKeyContainerInfo.HardwareDevice)
{
var cspParameters = new CspParameters
{
KeyContainerName = csp.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
using (var csp2 = new RSACryptoServiceProvider(cspParameters))
{
sig = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
}
else {
sig = csp.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
return sig;
}
FYI the CryptoAPI is being deprecated in favor of Cryptography API: Next Generation. One way to do what you want with CNG in C# would be with System.Security.Cryptography.Cng:
...
using (RSA rsa = new RSACng())
{
byte signature = rsa.SignData(message, hashAlgorithm, paddingMode);
...
}
add a comment |
It all depends on where your certificate is coming from. Like the MSDN comment says, if it's coming from Microsoft Base Cryptographic Provider, then it will not work with SHA256. This CSP came out with the first version of CryptoAPI back in 1996, and does not understand SHA256 because SHA256 was not around back then.
The way to check and handle this gracefully would be:
public byte SignData(RSACryptoServiceProvider csp, byte bytes)
{
byte sig = null;
if ((csp.CspKeyContainerInfo.ProviderType == PROV_RSA_FULL || csp.CspKeyContainerInfo.ProviderType == PROV_RSA_SCHANNEL) && !csp.CspKeyContainerInfo.HardwareDevice)
{
var cspParameters = new CspParameters
{
KeyContainerName = csp.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
using (var csp2 = new RSACryptoServiceProvider(cspParameters))
{
sig = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
}
else {
sig = csp.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
return sig;
}
FYI the CryptoAPI is being deprecated in favor of Cryptography API: Next Generation. One way to do what you want with CNG in C# would be with System.Security.Cryptography.Cng:
...
using (RSA rsa = new RSACng())
{
byte signature = rsa.SignData(message, hashAlgorithm, paddingMode);
...
}
It all depends on where your certificate is coming from. Like the MSDN comment says, if it's coming from Microsoft Base Cryptographic Provider, then it will not work with SHA256. This CSP came out with the first version of CryptoAPI back in 1996, and does not understand SHA256 because SHA256 was not around back then.
The way to check and handle this gracefully would be:
public byte SignData(RSACryptoServiceProvider csp, byte bytes)
{
byte sig = null;
if ((csp.CspKeyContainerInfo.ProviderType == PROV_RSA_FULL || csp.CspKeyContainerInfo.ProviderType == PROV_RSA_SCHANNEL) && !csp.CspKeyContainerInfo.HardwareDevice)
{
var cspParameters = new CspParameters
{
KeyContainerName = csp.CspKeyContainerInfo.KeyContainerName,
KeyNumber = csp.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
};
using (var csp2 = new RSACryptoServiceProvider(cspParameters))
{
sig = csp2.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
}
else {
sig = csp.SignData(bytes, CryptoConfig.MapNameToOID("SHA256"));
}
return sig;
}
FYI the CryptoAPI is being deprecated in favor of Cryptography API: Next Generation. One way to do what you want with CNG in C# would be with System.Security.Cryptography.Cng:
...
using (RSA rsa = new RSACng())
{
byte signature = rsa.SignData(message, hashAlgorithm, paddingMode);
...
}
answered Dec 2 '18 at 3:28
mnisticmnistic
7,1711923
7,1711923
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449086%2fx509certificate2-with-private-key-signing-data-using-sha256withrsa%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown