I have to write a standalone java program to decrypt password from file,using Symmetric key for password decryption. I didn't work with encryption and decryption before. can anybody give any suggestion how can i do this.I need your guidance.
maybe you need something like this
private static final String ALGORITHM = "AES";
....
....
Key key = new SecretKeySpec(new String("here is your symmetric key").getBytes(), ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
//dencript mode (passes the key)
c.init(Cipher.DECRYPT_MODE, key);
//Decode base64 to get bytes
byte[] encBytes = new BASE64Decoder().decodeBuffer(encryptedValue);
// Decrypt
byte[] plainTxtBytes = c.doFinal(encBytes);
// Decode
String decryptedValue = new String(plainTxtBytes , "UTF-8");
Here are some resources:
http://www.javamex.com/tutorials/cryptography/symmetric.shtml
http://www.java2s.com/Code/Java/Security/EncryptionandDecryptionusingSymmetricKeys.htm
http://www.flexiprovider.de/examples/ExampleCrypt.html (This uses files as well)
Related
I want to AES encrypt data for the http requests in flutter. I have password and plaintext string which I want to encrypt.
I am using flutter_string_encryption. I have achieved in iOS app but both the output differs.
final salt = await cryptor.generateSalt();
final generatedKey = await cryptor.generateKeyFromPassword(password, salt);
final String encrypted = await cryptor.encrypt(string, generatedKey);
Do you have any particular attachment to flutter_string_encryption? I wrote a custom package based off PointyCastle and written entirely in Dart which can solve AES for you.
https://pub.dev/packages/steel_crypt
It looks something like this implemented:
var fortunaKey = CryptKey().genFortuna(); //generate 32 byte key with Fortuna; you can also enter your own
var nonce = CryptKey().genDart(len: 12); //generate IV for AES with Dart Random.secure(); you can also enter your own
var aesEncrypter = AesCrypt(key: fortunaKey, padding: PaddingAES.pkcs7); //generate AES encrypter with key and PKCS7 padding
String encrypted = aesEncrypter.gcm.encrypt(inp: 'somedatahere', iv: nonce); //encrypt using GCM
String decrypted = aesEncrypter.gcm.decrypt(inp: encrypted, iv: nonce); //decrypt
AKushWarrior's answer is right but if you don't want to use salt key it's ok, you can directly go with your encryption key
encryptionKey ="qwertyuiop";//your encryption key
var Encrypter = AesCrypt(encryptionKey, 'cbc', 'pkcs7');
//using AES : CBC/ECB , encryptionKey and PKCS7 padding
EncryptedData = Encrypter.encrypt("hello world");//your data instead of Hello world
DecryptedData = Encrypter.decrypt(EncryptedData);
I am working with encryption using AES. My customer is encrypting some of the sensitive data while posting the data to my web API. And my code will decrypt these fields before insert them to the database.
Originally we agree to use a fixed secret key. Below is the code:
public class AESEncryptor {
private static final String ALGO = "AES";
private static final String keyVal = "!5Po4#j82Adsu39/*na3n5";
public static String encrypt(String data) {
try {
Key key = genKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(data.getBytes());
return Base64.encodeBase64String(encVal);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt (String encryptedData) throws Exception{
Key key = genKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] data = Base64.decodeBase64(encryptedData);
byte[] decByptes = c.doFinal(data);
return new String(decByptes);
}
private static Key genKey() throws Exception {
fixKeyLength();
return new SecretKeySpec(keyVal.getBytes(), ALGO);
}
}
Then the other party suggested we should switch to KeyGenerator to generate a random secure key. Something like the following.
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
final byte[] nonce = new byte[32];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(16 * 8, nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
I am not sure that is possible. Because the correct decryption relies on the same key for encryption. If the key is random, how would my API know what key to use every time? Or is there a solution to handle this situation?
There is no solution to handle this problem. Symmetric encryption requires that both parties know the key in order to encrypt and decrypt. If the key is random each time, then you need a way to communicate the key.
The scheme you have designed is quite poor, since a fixed key means that the key being compromised will bring down the whole system. You're also using ECB mode, which is inherently insecure. No authentication either.
If you want to communicate data securely from one party to another, use TLS with client authentication. This is the industry standard way to solve this problem and you don't have to get your hands dirty with the crypto.
I would like to use encryption to send traffic to my F5 BIG IP load balancer and have it use its own native CRYPTO:: methods to decrypt a base64 encoded string.
I am able to encrypt and decrypt a string within the appliance and within a Visual Studio 2012 console application but I cannot decrypt an encrypted string in the opposing environment.
Any suggestion here as to how to get the following keys in a compatible format that CRYPTO or C# understands would go a long way!
// C# key and vector declaration:
private const string AesIV = #"!QAZ2WSX#EDC4RFV";
private const string AesKey = #"5TGB&YHN7UJM(IK<";
It appears that in CRYPTO:: it needs it in hex format, I tried to convert it as seen below but that didnt help me.
C# console app code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;
using System.Threading;
namespace ssoconsole_encrypt
{
class Program
{
private const string AesIV = #"!QAZ2WSX#EDC4RFV";
private const string AesKey = #"5TGB&YHN7UJM(IK<";
// set key "abed1ddc04fbb05856bca4a0ca60f21e"
//set iv "d78d86d9084eb9239694c9a733904037"
// set key "56bca4a0ca60f21e"
// set iv "39694c9a73390403"
/// <summary>
/// AES Encryption
/// </summary>
///
static public string Encrypt(string text)
{
// AesCryptoServiceProvider
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = Encoding.UTF8.GetBytes(AesIV);
aes.Key = Encoding.UTF8.GetBytes(AesKey);
string keyme = BitConverter.ToString(aes.Key);
string ivme = BitConverter.ToString(aes.IV);
Console.WriteLine(string.Format("The converted key is: {0}",keyme));
Console.WriteLine(string.Format("The converted iv is: {0}", ivme));
Console.WriteLine(System.Text.Encoding.UTF8.GetString(aes.Key));
// Thread.Sleep(10000);
//Console.WriteLine(aes.Key.ToString());
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// aes.Padding = PaddingMode.Zeros;
// Convert string to byte array
//byte[] src = Encoding.Unicode.GetBytes(text);
byte[] src = Encoding.UTF8.GetBytes(text);
// encryption
using (ICryptoTransform encrypt = aes.CreateEncryptor())
{
byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
// Convert byte array to Base64 strings
return Convert.ToBase64String(dest);
}
}
/// <summary>
/// AES decryption
/// </summary>
static public string Decrypt(string text)
{
// AesCryptoServiceProvider
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = Encoding.UTF8.GetBytes(AesIV);
aes.Key = Encoding.UTF8.GetBytes(AesKey);
//aes.IV = Encoding.UTF8.GetBytes(#"01020304050607080900010203040506");
//aes.Key = Encoding.UTF8.GetBytes(#"01020304050607080900010203040506");
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Convert Base64 strings to byte array
byte[] src = System.Convert.FromBase64String(text);
try
{
// decryption
using (ICryptoTransform decrypt = aes.CreateDecryptor())
{
byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
// return Encoding.Unicode.GetString(dest);
return Encoding.UTF8.GetString(dest);
}
}
catch (CryptographicException e)
{
return e.ToString();
}
}
static void Main()
{
string username = "jschoombee";
string encrypted = Encrypt(username);
string decrypted = Decrypt(encrypted);
// string decrypted = Decrypt("epvhTN55JnnVV9DBn1Cbsg==");
// string decrypted = Decrypt(encrypted);
Console.WriteLine(string.Format("jschoombee encrypted is : {0}",encrypted));
Console.WriteLine(string.Format("the Decrypted username for jp is : {0}", decrypted));
Thread.Sleep(1000000);
}
}
}
This is the Console Output:
The converted key is: 35-54-47-42-26-59-48-4E-37-55-4A-4D-28-49-4B-3C
The converted iv is: 21-51-41-5A-32-57-53-58-23-45-44-43-34-52-46-56
5TGB&YHN7UJM(IK<
jschoombee encrypted is : tGG9Un6VqcAOTQawlxwRXg==
the Decrypted username for jp is : jschoombee
This it the F5 / TCL code:
when RULE_INIT {
set static::hexkey "355447422659484E37554A4D28494B3C"
log local0.info"====Rule_Init===="
log local0.info "Key is $static::hexkey"
log local0.info"================="
}
when HTTP_REQUEST_DATA {
set iv "2151415A325753582345444334524656"
set text_to_encrypt "jschoombee"
set enc_out_no_binary [CRYPTO::encrypt -alg aes-256-cbc -keyhex $static::hexkey -ivhex $iv $text_to_encrypt]
set dec_in [CRYPTO::decrypt -alg aes-256-cbc -keyhex $static::hexkey -ivhex $iv $enc_out_no_binary]
log local0.info "The decrypted NO binary $dec_in"
log local0.info "The Encrypted NO binary Base64 is: [b64encode "$enc_out_no_binary"]"
binary scan $enc_out_no_binary H* enc_hex
log local0.info "The Encrypted NO binary Hex is: $enc_hex"
log local0.info "This is the IV $iv"
HTTP::release
}
The F5/TCL Output Log File:
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: The decrypted NO binary jschoombee
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: The Encrypted NO binary Base64 is: Rlz4cC9SlpRyON4cZI+dtQ==
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: The Encrypted NO binary Hex is: 465cf8702f5296947238de1c648f9db5
Feb 11 13:05:45 AMS4-LB-01 info tmm1[9650]: <HTTP_REQUEST_DATA>: This is the IV 2151415A325753582345444334524656
There are some very strange things happening in your code regarding the key and IV.
First of all the key you've specified is 16 characters. In UTF-8 those result in 16 bytes. You are however specifying a key of 32 bytes (256 bits) in your C# code. Also be warned that many libraries (incorrectly) use AES-256 to mean Rijndael with a 256 bit block size. It's probably better to just use AES-128 and focus on making your protocol and code secure.
Second, a key can never be a character string. A character string normally is restricted with regards to which values can be used. E.g. control codes cannot be entered. This means that your key will never reach its intended strength. If you want to use a static key, you should specify it in hexadecimals as you do in your F5 code.
A static IV does not make much sense. The whole idea of the IV is to make sure that you will generate a different ciphertext if you encrypt a block with a value already processed. So please use a random IV, and place it in front of your ciphertext.
You seem to have the hang on using encoding/decoding on your plaintext (UTF-8) and ciphertext (Base 64). So please try and follow the advice given above and try again.
As illustrated in http://msdn.microsoft.com/en-us/library/vstudio/system.security.cryptography.rsacryptoserviceprovider.encrypt(v=vs.90).aspx I am trying to use an RSA key that is stored in a User Container to encrypt and decrypt a RijndaelManaged Key and IV that is stored in an app.config file (in an NT service).
To create the encrypted keys I did the following and then added the strings to the config file
CspParameters cp = new CspParameters();
cp.KeyContainerName = "ContainerName";
// Get the existing or create a new RSA Key
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
//Create a new instance of the RijndaelManaged class.
RijndaelManaged RM = new RijndaelManaged();
//Encrypt the symmetric key and IV.
byte[] EncryptedSymmetricKey = rsa.Encrypt(RM.Key, false);
byte[] EncryptedSymmetricIV = rsa.Encrypt(RM.IV, false);
string configKey = Convert.ToBase64String(EncryptedSymmetricKey));
string configIV = Convert.ToBase64String(EncryptedSymmetricIV));
When I go to use the Key and IV from the config file, I perform the following:
//Get the existing RSA Key from the USER Container identified by Provider in the appsettings
CspParameters cp = new CspParameters();
cp.KeyContainerName = "ContainerName";
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp))
{
//Decrypt the RijndaelManaged KEY and IV from the config file using the RSA Key
byte[] Encrypted_RM_Key = Convert.FromBase64String(AppSettings["configKey"]);
byte[] Encrypted_RM_IV = Convert.FromBase64String(AppSettings["configIV"]);
byte[] Decrypted_RM_Key = rsa.Decrypt(Encrypted_RM_Key, false);
byte[] Decrypted_RM_IV = rsa.Decrypt(Encrypted_RM_IV, false);
//Encrypt the file using RijndaelManaged
RijndaelManaged RM = new RijndaelManaged();
RM.Key = Decrypted_RM_Key;
RM.IV = Decrypted_RM_IV;
....
}
While the service is running RM.Key and RM.IV stay the same. If the service is restarted, the resulting byte arrays in RM.IV and RM.Key are different which causes any decryption attempt on data that was encrypted before the service was restarted to fail with a Padding Invalid error.
Question: If I am using the same RSA key on the same encrypted data from the config file, why are the resulting Key and IV values different when the service is restarted?
Note: This also happens if I decrypt the values in my OnStart() service method and then try to decrpyt the same values in a dll that has been added to the project.
Wild guess: is your service running as the user for which you stored the keys in the container? You can add some traces along the way (or debug) and see whether you get the same RSA key every time.
I am seeing the "Padding is invalid and cannot be removed" error when I call the method below to decrypt the string from a windows application. String was encrypted from an asp.net application. Both application references the same assembly. I am able encrypt and decrypt with out any problem from the asp.net application. Here is the main code where I do the encryption and decryption.
private static byte[] EncryptHelper(byte[] arrData, string Password, bool Encrypt)
{
//Create the SymetricAlgorithem object
SymmetricAlgorithm myAlg = new RijndaelManaged();
//define a salt value to derive the key.
byte[] salt = System.Text.Encoding.ASCII.GetBytes("hjkhj877ffasah");
//Instantiate Rfc2898DeriveBytes with the password and salt.
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(Password, salt);
myAlg.Key = key.GetBytes(myAlg.KeySize / 8);
myAlg.IV = key.GetBytes(myAlg.BlockSize / 8);
myAlg.Padding = PaddingMode.PKCS7;
//Create the ICryptoTransform Object
ICryptoTransform encrytptor = Encrypt ? myAlg.CreateEncryptor() : myAlg.CreateDecryptor();
//Create Memorystream to write the encrypted data
using (MemoryStream aStream = new MemoryStream())
{
//Create the CryptoStream Ojbect using the aStream object
using (CryptoStream encryptStream = new CryptoStream(aStream, encrytptor, CryptoStreamMode.Write))
{
//Write the contents to crypto stream
encryptStream.Write(arrData, 0, arrData.Length);
//Flush the cryptostream
encryptStream.FlushFinalBlock();
//Reposition the memorystream to write the contents to an array.
aStream.Position = 0;
}
aStream.Flush();
//Convert to an array and return
return aStream.ToArray();
}
}
This is the method I use to convert the plain text from/to byte array
private static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
private static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
For persist the cipher text to database I use Convert.ToBase64String() and Convert.FromBase64String. Is the problem is with the way I use Rfc2898DeriveBytes class?
Well I think it's important to mention that from a security perspective, you are going to have the same IV for every message with the same password, and a predictable IV is a really big no no.
After that point I kinda don't want to look at it more to see what's going wrong, there are a lot of really bad cut and paste C# encryption on stackoverflow, and they just sit there with no mechanism for update, no one looking at them again except for people finding them to cut and paste again.
Look at Modern Examples of Symmetric Authenticated Encryption of a string. c#.
I try to keep it up to date and reviewed.