I have a client certificate files (.perm,.csr,.pfx,.key) and these files contain hex code
The below code snippet takes a cipherText and performs some validation. This is a servlet and the cipherText is passed as a request paramter. I looked into cert files and provided all the hex code available in those files as input but nothing seem to work.
Looking at the way its decoded can anyone tell what kind of input its expecting from the certificate files:
validate(cipherText)
private static final byte[] desKeyData = {
(byte)0xA2, (byte)0x15, (byte)0x37, (byte)0x07, (byte)0xCB, (byte)0x62,
(byte)0xC1, (byte)0xD3, (byte)0xF8, (byte)0xF1, (byte)0x97, (byte)0xDF,
(byte)0xD0, (byte)0x13, (byte)0x4F, (byte)0x79, (byte)0x01, (byte)0x67,
(byte)0x7A, (byte)0x85, (byte)0x94, (byte)0x16, (byte)0x31, (byte)0x88 };
byte[] bCipherText = Base64.decode(CipherText);
Cipher oC3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
SecretKeySpec oKey = new SecretKeySpec(s_desKeyData , "DESede");
IvParameterSpec oIvSpec = new IvParameterSpec(s_baIV);
oC3des.init(Cipher.DECRYPT_MODE, oKey, oIvSpec);
byte[] plaintext = oC3des.doFinal(bCipherText );
return new String(plainText, Charset.forName("UTF-8"));
Related
I am trying to encrypt the text in C# using google KeyManagementService.
I am not able to decrypt the cipher generated by KeyManagementServiceClient.Encrypt using KeyManagementServiceClient.Decrypt method. Decryption gives me:
Grpc.Core.RpcException: Status(StatusCode=InvalidArgument, Detail="Decryption failed: the ciphertext is invalid.")
I tried to use the google Try this API link to get the cipher and the length of the cipher generated by google API and the C# result are different.
Ex:
plaint text: text
cipher from C#:
TaRQSJ2KXrdmJJT6MmlD8RrcxzPJEa1jwAXWJ1puXg6nbl80aBcSLQBqSYOONfXhpZx8SyxCdB6mqTgr8uLJoAjva+Q4kN/p0+9RL2Sp2mHq4wjmZQ==
cipher from API:
TaRQSJ2KXv9ntnS7IszL077KNPtGJnqF9pSNiWANsq8gD0whezUSKwBqSYOOKKMifiWrfPDnHL5xETHPPlms0ztjkqa5hjdtkHwpzByLzi68A40
Has anyone phased the issue?
Here is my sample code
KeyManagementServiceClient keyManagementServiceClient =KeyManagementServiceClient.Create(channel);
byte[] plaintext=Encoding.ASCII.GetBytes("test");
EncryptRequest request = new EncryptRequest
{
CryptoKeyPathName = new CryptoKeyPathName("test-project", "global", "test-key", "encryption-key"),
Plaintext = ByteString.CopyFrom(plaintext),
};
EncryptResponse response =keyManagementServiceClient.Encrypt(request);
var cipher =
Convert.ToBase64String(response.Ciphertext.ToByteArray());
//Decrypt
ByteString ciphertext = ByteString.CopyFrom(Encoding.ASCII.GetBytes(cipher));
DecryptRequest req = new DecryptRequest
{
CryptoKeyName = new CryptoKeyName("test-project", "global", "test-key", "encryption-key"),
Ciphertext = ciphertext,
};
// Make the request
DecryptResponse res = keyManagementServiceClient.Decrypt(req);
You've base64-encoded the results of encrypting, but you haven't base64-decoded it before you try to decrypt it.
In the line
ByteString ciphertext = ByteString.CopyFrom(Encoding.ASCII.GetBytes(cipher));
It should instead look something like
ByteString ciphertext = ByteString.FromBase64(cipher);
(Note also that the ByteString class has built-in methods for going to/from Base64, if that's what you're looking to do.)
I am developing a website by using ASP.NET. I want to implement login authentication for my users. I am using SALT HASH method to securely save users' passwords to the DB. By looking at various codes I wrote a code like below to generate the SALT and the Hashed passwords to store in Database.
private string hashedPassword;
private string Salt;
private string SaltPlusPassword;
private const byte saltSize = 24;
byte[] saltArray;
byte[] hashedPasswordArray;
byte[] bytes;
public void Save_Login(string passWord)
{
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
saltArray = new byte[saltSize];
rng.GetBytes(saltArray);
}
Salt = Convert.ToBase64String(saltArray);
SaltPlusPassword = String.Format("{0}{1}", Salt, passWord);
using (SHA256 sha = SHA256.Create())
{
bytes = Encoding.UTF8.GetBytes(SaltPlusPassword);
hashedPasswordArray = sha.ComputeHash(bytes);
}
hashedPassword = Convert.ToBase64String(hashedPasswordArray);
}
//Salt will be save to DB
//hashedPassword will be save to DB.
So I have few questions.
1) I read in an article that saying "make your salt is at least as long as the hash function's output" ok. What are the sizes for saltArray, hashedPasswordArray and bytes arrays which are declared in my code? I used saltArray size as 24. Is it ok?
2) What will happen if I use ?
bytes = Encoding.Unicode.GetBytes(SaltPlusPassword);
instead of
bytes = Encoding.UTF8.GetBytes(SaltPlusPassword);
3) What is the datatype should I use to store salt and the hashed password in the DB? ( My db is MYSQL )
4) Is there any performance difference if I use SHA256Managed instead of SHA256? Which is best?
5) Finally am I doing this in the right way? What are the weaknesses in above code? What are your suggestions?
Rather than deal with all these issues, why not use the built in identity management tools provided by ASP.NET. See here
http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity
Much more common and robust.
I need to support the following signature:
Sign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google Developers Console. The output will be a byte array.
The following code fails, with "Invalid algorithem specified". Is this a limitation of .NET? Here is a snippet of my code:
var rsa2 = new RSAPKCS1SignatureFormatter(rsa);
rsa2.SetHashAlgorithm("SHA256");
bytes = rsa2.CreateSignature(bytes);
The above requirement is from computing the signature for a Server to Server Applications for Google API.
https://developers.google.com/accounts/docs/OAuth2ServiceAccount#computingsignature
Thanks for any help.
Karl..
Here is the code that signs the JWT. I've removed the use of RSAPKC1SingatureFormatter class and using another HASHCompute method in an effort to get something to work (still not working)
I'm not sure this is correct and unfortunately my response from the Rest service is always the same "Invalid Grant" so hard to tell.
public string Generate(string HeadJWT, string ContentJWT, X509Certificate2 certificate)
{
var bytes = Utility.getBytes(HeadJWT);
var base64Head = Utility.Base64UrlEncode(bytes);
// base64 Url Encode Payload (Json Content)
bytes = Utility.getBytes(ContentJWT);
var base64Payload = Utility.Base64UrlEncode(bytes);
var secureInputValue = String.Format("{0}.{1}", base64Head, base64Payload);
bytes = Stub.Jwt.Utility.getBytes(secureInputValue);
bytes = Stub.Jwt.Utility.ComputeHMACSha265(bytes, certificate.PublicKey.EncodedKeyValue.RawData);
_signature = Stub.Jwt.Utility.Base64UrlEncode(bytes);
return String.Format("{0}.{1}.{2}", base64Head, base64Payload, _signature);
}
This cannot be a limitation of .NET in general, as the example Microsoft code seems to use "SHA256" itself. But it could be a limitation of your particular runtime.
I have created a wesite in asp.net and use ms-sql database to save the records. Now want to convert it in node.js application. And want to use same sql database. In asp.net application I have encrypt the password for registered user. Below is code.
public static string CreateHash(string unHashed)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.ASCII.GetBytes(unHashed);
data = x.ComputeHash(data);
return System.Text.Encoding.ASCII.GetString(data);
}
public static bool MatchHash(string HashData, string HashUser)
{
HashUser = CreateHash(HashUser);
if (HashUser == HashData)
return true;
else
return false;
}
Now problem is that how I use same encryption in node.js. So when node application is ready old user can also make login. It only possible if node app also use same encryption that I have use in asp.net.
For node I have created all environment and use mssql module for database communication. Please help me fix that. Thanks!!
First of all MD5 shall no longer be used if you are serious about security.
Based on your comment and code, I fear there is a 'data loss' in the initial ASP.net code.
Let us have a look at CreateHash function again, I've added comments:
public static string CreateHash(string unHashed)
{
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
// Convert unHashed string to bytes using ASCII coding
byte[] data = System.Text.Encoding.ASCII.GetBytes(unHashed);
// Compute MD5 hash from bytes
data = x.ComputeHash(data);
// Decode MD5 resulting bytes as ASCII
return System.Text.Encoding.ASCII.GetString(data);
}
The last line confuses me, it is decoding bytes received from MD5 function as if they were ASCII, but that is incorrect assumption. And the resulting encoded string as you gave in comment contains lots of "?'s".
Next node.js code will do similar except encode the string using hex rather than ascii:
var crypto = require('crypto')
function createHash(data) {
return crypto.createHash('md5').update(data, 'ascii').digest('hex')
}
To emulate "bytes to ascii" you could try .digest('binary') instead of hex. If it does not give what you expect, then you have to make a separate 'conversion' step from hex to ascii. (I am not experienced enough to give you elegant solution to the later one)
I've created an encryption key by the following code:
SecretKeyFactory skFactory = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede");
SecretKey key = skFactory.generateSecret(new PBEKeySpec("<some password>".toCharArray()));
Then I've used the key to encrypt some text.
I've stored this key inside a java key store and saved in on FS:
KeyStore ks = KeyStore.getInstance("JCEKS");
ks.setKeyEntry(keyAlias, key ,keyPassword.toCharArray(), null);
FileOutputStream fileOutputStream = new FileOutputStream (keyStorePath);
keyStore.store(fileOutputStream , keyStorePassword.toCharArray());
fileOutputStream.close();
In a different process I open the key store and try to decrypt some text:
KeyStore ks2 = KeyStore.getInstance("JCEKS");
ks2.load(new java.io.FileInputStream(keyStorePath), ksPassword.toCharArray());
SecretKeyFactory skFactory2 = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede");
String passForTheKey = ks2.getKey(keyAlias, keyPass.toCharArray()).toString();
KeySpec key = new PBEKeySpec(passForTheKey.toCharArray());
SecretKey sKey2 = skFactory.generateSecret(key);
When trying to decrypt the text I get the error:
java.security.InvalidKeyException: Given final block not properly padded
If I try to use the key without storing it in the key store immediately after creating it, the decription proccess is working great.
Any ideas?
You're storing the actual secret key in your keystore (which is normal). However, you seem to be trying to read it as a password, for a new key you're generating later.
Instead of this:
String passForTheKey = ks2.getKey(keyAlias, keyPass.toCharArray()).toString();
KeySpec key = new PBEKeySpec(passForTheKey.toCharArray());
SecretKey sKey2 = skFactory.generateSecret(key);
use this:
SecretKey sKey2 = (SecretKey) ks2.getKey(keyAlias, keyPassword.toCharArray());
What you're reading from the keystore is the key itself (as you've stored it), not some password. (generateSecret will just generate a new key.)