I am having an issue where a file containing usernames and passwords is able to be decrypted on some machines but is failing on another.
The machine that it fails on is a brand new installation of Windows 7 embedded. All that has been installed is my application and .net service pack 4.6.2
I did not write this code originally but I need to get it working on the Win 7 embedded machines.
The error I am seeing is:
UserManager error: Error reading C:\CutterBuild\Data\Config\users.xml :System.Security.Cryptography.CryptographicException: Key not valid for use in specified state.
The relevant code is:
try
{
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(inputFilePath);
System.Security.Cryptography.CspParameters cspParams = new System.Security.Cryptography.CspParameters();
cspParams.KeyContainerName = KEY_CONTAINER_NAME;
// Next line is Where the code fails and throws exception!!!!.
System.Security.Cryptography.RSACryptoServiceProvider rsaKey = new System.Security.Cryptography.RSACryptoServiceProvider(cspParams);
EncryptionHelper.Decrypt(xmlDoc, rsaKey, KEY_NAME);
reader = new XmlNodeReader(xmlDoc);
collection = Read(reader, out errorMessage);
}
I did some debugging and everything looks good up to the rsa key point. The Microsoft documentation on the error is no help.
I did some reading on this and found it confusing, It states in the documentation that you need to create a security certificate, but I can't find any instructions on how to do this. And shouldn't it be created on one machine and copied to others? Where does it get copied to? I can't find anything about it on my PC, but the decrypt is working fine on my PC.
Can anyone point me in the right direction?
Related
We have created a signature in a .Net Core web api, using X509Certificate2.GetECDsaPrivateKey on a .pfx certificate file, and need to verify this signature in our Xamarin Android app, using the public key (.crt). I can run the code on a normal Windows .Net Framework 4.6.1 app and it works. If I change the Framework version to anything lower, my app doesn't compile, as the GetECDsaPublicKey method was only implemented in 4.6.1. In my Xamarin app, I can compile the app and it runs, but as soon as I reach the line that executes the GetECDsaPublicKey method, I get a NotImplemented exception. There is literally no information on this on the internet, apart from the Microsoft documentation, which doesn't give much in any case. Can anyone shed any light onto why this error occurs? Here are the few lines of code to load the certificate and verify the signature (I've taken out some unnecessary error checking code):
string FileName = "public_key.crt";
string certPath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), FileName);
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath);
System.Security.Cryptography.ECDsa eCDsa = certificate.GetECDsaPublicKey(); // This line causes the exception
Even just executing this line, gives the same error:
System.Security.Cryptography.ECDsa eCDsa = System.Security.Cryptography.ECDsa.Create();
So if anyone comes across this also struggling with it, there is a post that answers this question - Are ECDSA and ECDH available for mono?
Sadly, we will have to either use a different encryption/signing algorithm or use something like BouncyCastle...
Our organization recently adopted Box to replace Windows shared folders. The small development group I'm a part of will need to upload and download files from at least one Box share and so we are just getting started with the API.
Our group currently uses Visual Studio 2013 to develop in C# with a preferred target of .NET 4.0. The current version of the SDK (2.15.6) isn't compatible with our platform but looking at prior versions it appears we should be able to leverage version 2.12.1 with our existing platform. The SDK includes a solution with C# methods to access the API calls and a solution with sample code.
Presently I'm trying to get the sample code to consume my credentials and authenticate to the server.
Within the Box developer tools I have created an application and used the built-in Box configuration option to generate a Public/Private keypair which is presented as a JSON file.
Where I'm getting hung up is when I try to use the keypair with the Box.V2.Samples.JWTAuth project. I copied the private key out of the JSON file, replaced the \n's with actual carriage returns, and pasted it into the private_key.pem file:
Private Key
I placed the other values in app.config and started the console app, which produces an Unable to cast error:
Error message
How can I get from a BouncyCastle RsaPrivateCrtKeyParamaters object to a BouncyCastle AsymmetricCipherKeyPair object?
Edit
I was able to track down the problematic code block. From SDK\Box.V2.JWTAuth\BoxJWTAuth.cs:
var pwf = new PEMPasswordFinder(this.boxConfig.JWTPrivateKeyPassword);
AsymmetricCipherKeyPair key;
using (var reader = new StringReader(this.boxConfig.JWTPrivateKey))
{
key = (AsymmetricCipherKeyPair)new PemReader(reader, pwf).ReadObject();
}
var rsa = DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)key.Private);
this.credentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
From my reading it seems like the code is anticipating having to extract the Private key from a Public/Private pair which isn't what Box is supplying (at least, not currently) and what I'm supplying appears to already be of the RsaPrivateCrtKeyParameters type so this cast may (no longer be) necessary.
It's not clear from your question whether you are trying to write code to do this, or trying to configure a tool, but programmatically, it would be:
RSAPrivateCrtKeyParameters priv = ...;
RSAKeyParameters pub = new RSAKeyParameters(false, priv.getModulus(), priv.getPublicExponent());
AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv);
I wanted to check the trust of the one of the .exe file in our project for which I am using C#.
I have referred - http://pinvoke.net/default.aspx/wintrust/WinVerifyTrust.html
Here is my code snippet.
WinTrustData wtd = new WinTrustData(filename);
Guid guidAction = new Guid(WINTRUST_ACTION_GENERIC_VERIFY_V2);
WinVerifyTrustResult result = WinVerifyTrust(INVALID_HANDLE_VALUE, guidAction, wtd);
bool valid = (result == WinVerifyTrustResult.Success);
filename - is nothing but .exe file path.
WinVerifyTrust() mentioned in above code returns "WinVerifyTrustResult.Success" only if machine is connected to internet at least once.
However on fresh machine it returns "0x800b0100" i.e.- "Trust_e_nosignature".
Is it expected behavior? If yes then how to resolve it?
I searched for this specific behavior but did not found any satisfactory answer.
Windows (7+) is shipped with a very limited set of root certificates.
Those are downloaded on demand. This could be the reason why the authenticode signature could not be verified if a computer was never connected to the internet before (but still, I suppose that just connecting to the internet is not sufficient, but some surfing to https pages or verifying the authenticode signature is necessary so that the "right" root certificate is downloaded).
You can verify this by checking/counting the ca certificates which are installed in the internet explorer before and after connecting to the internet.
I'm trying to understanding why in .NET, calling the constructor System.Security.Cryptography.X509Certificates.X509Certificate2() fails with an "internal error" when a file name and matching password are passed. This happens on a Windows 2008 R2 server. On a different machine, running Windows 7, the call works properly using the same file name and password (actually, I tried with two different pairs of files and passwords and got the same results). I'm hoping that there's just some setting that must be enabled (or disabled) on the Windows 2008 R2 server for this command to work. (The server has much more stringent security, so maybe it's blocking something?) But to better understand the problem, I guess I need to get a better sense of what .X509Certificate2() is actually doing.
For starters, the following two commands work fine on both machines:
var x = new X509Certificate2();
var y = new X509Certificate2(fullFilePath);
However, any of the overloads that take a password will fail on the Windows 2008 R2 server if the password is correct, but not on the Windows 7 machine. (Both are 64-bit.) For example:
var z = new X509Certificate2(fullFilePath, password);
If I pass an incorrect or blank password (on either machine), then I get "The specified network password is not correct." However, if the password is correct, then the Windows 2008 R2 server says "An internal error occurred."
This leads me to believe that somewhere in the X509Certificate2 code, if the password is found to match, then another action is taken, and that's the one that's failing.
I did find some information on the source code through a Google search that brought me here:
http://www.dotnetframework.org/default.aspx/4#0/4#0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/security/system/security/cryptography/x509/X509Certificate2#cs/1305376/X509Certificate2#cs
... but I'm still having some difficulty understanding what's going on. Apparently, no matter what parameters are passed, they're dealt with somehow in this line:
m_safeCertContext = CAPI.CertDuplicateCertificateContext(this.Handle);
...but I haven't been able to find the source code for that yet.
What I'm hoping, actually, is to find that maybe someone knows that "oh yes, on Windows 2008 servers, you have to make sure that xyz is enabled for X509Certificate2() to work, and all you have to do is..." or that there must be something else on the machine besides that file being there in the specified place for the constructor to work.
My end goal is to have program working on the server, in the same way as it works on the other machine. However, just having some information on the logic of exactly what happens when I make this call (and what gets executed after it finds that the password matches) would help immensely.
Any insights are appreciated!
Try
var certificate = new X509Certificate2(fileName, password, X509KeyStorageFlags.MachineKeySet);
My problem is that I have an application on .net is mvc
The application make "Facturas Electronicas" for the company that I work.
If I run the application on my computer from the visual studio, the application works fine.
But if I publish the app to another server the application doesn't make the "Factura Electronica", but before this erros the application works fine on other servers.
All started when I publish another app with the same code, and needs the same certificates but it is to other product and i need the two applications.
After checking all the code I realize that the problem was the certificate a pfx file,
when the app try to execute this
X509Certificate2 cert = new X509Certificate2(certificadoDemo, claveCertificadoDemo);
the navigator return this
This webpage is not available
the expiration of the pfx file is until july 2014
Do anyone knows what is going on?
adding this
X509KeyStorageFlags.MachineKeySet
to that line of code i resolved the problem
this is the new line of code
X509Certificate2 cert = new X509Certificate2(certificadoDemo, claveCertificadoDemo, X509KeyStorageFlags.MachineKeySet);
thanks
Your question cannot be answered without a detailed exception. Either turn off customErrors in the web.config file (in which case, the entire exception will be sent to the browser) or catch errors in Global.asax Application_Error event handler and log the errors to a file somehow (using System.Diagnostics preferably). Without more sample code, we can't even know which constructor you're calling because X509Certificate2 has 5 constructors which take two parameters. See http://sscce.org/ on how to ask questions.