How to encrypt images in java - encryption

Need advice on this as I am still unable to encrypt /decrypt a images successfully in java.
For the user to decrypt the image, the user has to click the image and enter the image password, similar to a password protected text file or pdf file.
Below is the function for encryption Image in java
public static void ImgEncrypt()throws Exception{
// Scanner to read the user's password. The Java cryptography
// architecture points out that strong passwords in strings is a
// bad idea, but we'll let it go for this assignment.
Scanner scanner = new Scanner(System.in);
// Arbitrary salt data, used to make guessing attacks against the
// password more difficult to pull off.
byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };
{
File inputFile = new File("C:/rose.jpg");
BufferedImage input = ImageIO.read(inputFile);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
// Get a password from the user.
System.out.print("Password: ");
System.out.flush();
PBEKeySpec pbeKeySpec = new PBEKeySpec(scanner.nextLine().toCharArray());
// Set up other parameters to be used by the password-based
// encryption.
PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20);
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Make a PBE Cyhper object and initialize it to encrypt using
// the given password.
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
FileOutputStream output = new FileOutputStream("C:/output.jpg");
CipherOutputStream cos = new CipherOutputStream(
output, pbeCipher);
//File outputFile = new File("image.png");
ImageIO.write(input,"JPG",cos);
cos.close();
}
}

The only way that you can decrypt when you open a file is when it is a self decrypting file - an executable which the operating system can run, or when the associated application contains a protocol for decryption. You cannot just click on a file you encrypted yourself and expect it to work.

Related

How do i store sensitive data (such as Database passwords) in an Oracle Database

Basically i'm building a WebApp (ASP.NET MVC5) working with Oracle Database. The application connects to multiple oracle databases and an admin should be able to dynamically add new database connections to the webapp.
The way we are doing it now, when an admin adds a new database via the admin panel, the database connection info is stored in our own Oracle Database (this includes the username and password to the database). These passwords are currently stored plaintext.
All the webapp would have to do is retrieve the database credentials from our own database, format them into a connection string and connect to the database.
The problem is, if we hash the passwords, they will not work in a connection string, nor would this add any security at all. All the encryption of these passwords should happen on the databas-side.
I found out about TDE (transparant data encryption) but i believe this is only available in the enterprise edition of Oracle Database and i do not have access to this. Is there any other way to securely store the database passwords? Am i missing something ?
You can simply encrypt the passwords and store it in the database. When a user changes the password or signs up for the first time, simply encrypt them. While checking for validation, encrypt the text box and check if two strings match.
And when you require to know the passwords, decrypt them.
A sample code for encryption looks like
// Encrypt the text
public static string EncryptText(string strText)
{
return Encrypt(strText, "a#94tOc*"); // use any string to encrypt other than a#94tOc*
}
//The function used to encrypt the text
private static string Encrypt(string strText, string strEncrKey)
{
byte[] byKey = { };
byte[] IV = { 0X12, 0X34, 0X56, 0X78, 0X90, 0XAB, 0XCD, 0XEF };
byKey = System.Text.Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = System.Text.Encoding.UTF8.GetBytes(strText);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
Similarly for decrypting, use:
//Decrypt the text
public static string DecryptText(string strText)
{
return Decrypt(strText, "a#94tOc*"); // use same as encryption string
}
//The function used to decrypt the text
private static string Decrypt(string strText, string sDecrKey)
{
byte[] byKey = { };
byte[] IV = { 0X12, 0X34, 0X56, 0X78, 0X90, 0XAB, 0XCD, 0XEF };
byte[] inputByteArray = new byte[strText.Length + 1];
byKey = System.Text.Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
inputByteArray = Convert.FromBase64String(strText.Replace(' ', '+'));
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
return encoding.GetString(ms.ToArray());
}
So basically just call EncryptText(password) to encrypt and DecryptText(encrypted_password) to decrypt.

How can I read an encrypted text from a file and decrypt it?

I have some account info that is being encrypted and written to a file like this:
//imports here
public class Main
public static void main(String[] args) {
try {
String text = "this text will be encrypted";
String key = "Bar12345Bar12345";
//Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
//encrypt text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encrypted = cipher.doFinal(text.getBytes());
write(new String(encrypted));
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
public static void write(String message) {
BufferedWriter bw = null;
FileWriter fw = null;
try {
String data = message;
File file = new File(FILENAME);
if (!file.exists()) {
file.createNewFile();
}
fw = new FileWriter(file.getAbsoluteFile(), true);
bw = new BufferedWriter(fw);
bw.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
So the contents of the file is one string without any breaks in between. If I wanted to decrypt the string, I would do this:
String key = "Bar12345Bar12345";
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
byte[] encrypted = text.getBytes();
cipher.init(Cipher.DECRYPT_MODE, aesKey);
String decrypted = new String(cipher.doFinal(encrypted));
System.err.println(decrypted);
This works fine as long as byte[] encrypted is the same as used as in the encrypting process, but when I try to read the encrypted text from the file using a FileReader and a BufferedReader and change it into a byte using lines.getByte() it throws the exception
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
Compare the cipher text from the encrypting process with the cipher text from lines.getByte() before you try to do any decryption. They are most likely different. Try reading the entire file into a byte[] first before decrypting it. Symmetric ciphers need to do their work on blocks of the same size, in this case 16 bytes.
I would also be remiss if I didn't comment on some of the poor protocol choices.
Hard coded key - Your encryption key should never be hard-coded in your application. If you ever need to change your encryption key, you are not able to do so. If your application is distributed to end users, it's easy for them to recover the key using an application like strings.
You are using ECB as your mode of operation. ECB has several ways it can be attacked, such as block shuffling, which can allow an attacker to decrypt data without having the encryption key.
Encryption is hard to get right on your own. Consider solving your problem a different way.
You are trying to treat your encrypted array contents as (platform encoded) text, while it is not - it consists of random bytes.
You either need to create a binary file by writing the contents of encrypted to it directly. That or you can create a text file by first encoding encrypted to base64.
Currently you are trying to read lines, but there aren't any. And if there are some line endings in there they will be stripped from the ciphertext before those bytes can be decrypted.
If you perform new String(encrypted) then it is also possible that you lose part of your data, as unsupported encodings are removed from the string without warning.
Note that the word "ciphertext" is a bit misleading; modern ciphers such as AES handle binary data, not text.

AES Encryption between C# and F5 load balancer / TCL

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.

Padding is invalid and cannot be removed with Rijndael decryption

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.

standalone java program to decrypt password

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)

Resources