I have DESCrypto in C# and Java as follows. I get the correct results when using C#. I get problem when using Java. How to resolved this problem?
// This is in the main function which will call the crypto function in the security class (C#).
private void button1_Click(object sender, EventArgs e)
{
string plainText = "0123456789";
Debug.WriteLine("plainText:" + plainText );
// plainText:0123456789
byte[] encrypted = Security.Encrypt(Encoding.ASCII.GetBytes(plainText));
Debug.WriteLine("encrypted:" + Security.GetString(encrypted));
// encrypted:4F792B474936462B6A4F62635A6142464D54782F4E413D3D
byte[] decrypted = Security.Decrypt(encrypted);
Debug.WriteLine("decrypted:" + Encoding.ASCII.GetString(decrypted)); //
// decrypted:0123456789
}
// This is a security class (C#)
public class Security
{
private static byte[] IV_64 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
private static byte[] KEY_64 = new byte[] { 7, 1, 7, 7, 5, 5, 4, 7 };
public static byte[] GetBytes(string value)
{
SoapHexBinary shb = SoapHexBinary.Parse(value);
return shb.Value;
}
public static string GetString(byte[] value)
{
SoapHexBinary shb = new SoapHexBinary(value);
return shb.ToString();
}
public static byte[] Decrypt(byte[] value)
{
MemoryStream mstream = new MemoryStream(Convert.FromBase64String(Encoding.ASCII.GetString(value)));
CryptoStream cstream = new CryptoStream(mstream, new DESCryptoServiceProvider().CreateDecryptor(KEY_64, IV_64), CryptoStreamMode.Read);
StreamReader reader = new StreamReader(cstream);
return Encoding.ASCII.GetBytes(reader.ReadToEnd());
}
public static byte[] Encrypt(byte[] value)
{
MemoryStream mstream = new MemoryStream();
CryptoStream cstream = new CryptoStream(mstream, new DESCryptoServiceProvider().CreateEncryptor(KEY_64, IV_64), CryptoStreamMode.Write);
StreamWriter writer = new StreamWriter(cstream);
writer.Write(Encoding.UTF8.GetString(value));
writer.Flush();
cstream.FlushFinalBlock();
mstream.Flush();
return Encoding ASCII.GetBytes(Convert.ToBase64String(mstream.GetBuffer(), 0, Convert.ToInt32(mstream.Length)));
}
}
// This is in the main function which will call the crypto function in the security class (Java).
String plainText = "0123456789";
Log.d("test", String.format("plainText:%s\n", plainText));
// plainText:0123456789
byte[] encrypted = Security.Encrypt(plainText.getBytes());
Log.d("test", String.format("encrypted:%s\n", Security.GetString(encrypted)));
// encrypted:3B2F8623A17E8CE6DC65A045313C7F34
byte[] decrypted = Security.Decrypt(encrypted);
Log.d("test", String.format("decrypted: %s\n", String.valueOf(decrypted)));
// decrypted:[B#6801b34
//This is a security class (JAVA)
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Security {
private static byte[] IV_64 = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
private static byte[] KEY_64 = new byte[] { 7, 1, 7, 7, 5, 5, 4, 7 };
private static String KEY_TYPE = "DES";
private static String ALGORITHM = "DES/CBC/PKCS5Padding";
public static String GetString(byte[] value) {
StringBuilder builder = new StringBuilder();
for (byte i : value) {
builder.append(String.format("%02X", i & 0xff));
}
return builder.toString();
}
public static byte[] GetByte(String value) {
StringBuilder builder = new StringBuilder();
for (char i : value.toCharArray()) {
builder.append(String.format("%02X", i & 0xff));
}
return String.valueOf(builder).getBytes();
}
public static byte[] Encrypt(byte[] value) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(KEY_64, KEY_TYPE), new IvParameterSpec(IV_64));
return cipher.doFinal(value);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
public static byte[] Decrypt(byte[] value) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY_64, KEY_TYPE), new IvParameterSpec(IV_64));
return cipher.doFinal(value);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
}
In java, when plainText = "0123456789", expected output from encryption is 4F792B474936462B6A4F62635A6142464D54782F4E413D3D (like in C#), but I get 3B2F8623A17E8CE6DC65A045313C7F34.
In C#, you're encoding the ciphertext with Base64 inside of the Security class and then you encode it again with Hex outside of it. In Java, you're only doing the Hex encoding. You should stick to one encoding and not combine two.
Other considerations:
DES should really not be used nowadays. It's rather easy to brute-force.
If you use CBC mode, then you need to use a new and unpredictable IV every time (randomly generated). It doesn't have to be secret, so you can prepend it to the ciphertext and slice it off before decryption.
You really should be thinking about adding authentication to the ciphertext. Otherwise, it may be possible to run a padding oracle attack in your system. Either use an authenticated mode like GCM or EAX, or use an encrypt-then-MAC scheme with a strong MAC like HMAC-SHA256.
Related
Actually I am trying to add Aes Encryption and decryption functionality inside my android app. During encryption it will give me crash in my motoG5 S plus device but its working properly inside my One Plus device.
Here is my Code: AesUtil.Java
public class AesUtil {
private int keySize = 256;
private int iterationCount = 1000 ;
private Cipher cipher;
private final String salt = "36e8fc9a6adf090665f459a7ad1b864d";
private final String iv = "ab00b7ea4e88500f2f0a17a7b5c7bcb1";
private final String passphrase = "ArknRQxD1YgaSFRHrjYazX7JMrlRxTERdkQx0dhENVlz";
public AesUtil() {
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw fail(e);
}
}
public String encrypt(String plaintext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, plaintext.getBytes("UTF-8"));
return Base64.encodeBase64String(encrypted);
}
catch (UnsupportedEncodingException e) {
throw fail(e);
}
}
public String decrypt(String salt, String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
return new String(decrypted, "UTF-8");
} catch (Exception e) {
throw fail(e);
}
}
private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));
return cipher.doFinal(bytes);
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
throw fail(e);
}
}
public SecretKey generateKey(String salt, String passphrase) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
return key;
}
catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
return null;
}
}
public static byte[] base64(String str) {
return Base64.decodeBase64(str);
}
public static byte[] hex(String str) {
try {
return Hex.decodeHex(str.toCharArray());
}
catch (DecoderException e) {
throw new IllegalStateException(e);
}
}
private IllegalStateException fail(Exception e) {
e.printStackTrace();
return null;
} }
Call Function in my main activity:
String encryptedText=AesUtil().encrypt("codeinsidecoffee")
Error Log Inside Moto G5s Plus:
java.lang.NoSuchMethodError: No static method encodeBase64String([B)Ljava/lang/String; in class Lorg/apache/commons/codec/binary/Base64; or its super classes (declaration of 'org.apache.commons.codec.binary.Base64' appears in /system/framework/org.apache.http.legacy.boot.jar)
at com.justcodenow.bynfor.utils.AesUtil.encrypt(AesUtil.java:40)
Method1: This method is available since version 1.4 of the Apache Commons Codec. If the OS of the phone has only an older version of the Codec package, the method won't be available. Alternatively, we can use a method that exists in older versions.
Instead of:
String encodedString = Base64.encodeBase64String(bytes);
Use:
String encodedString = new String(Base64.encodeBase64(bytes));
And for decoding, instead of:
byte[] bytes = Base64.decodeBase64(encodedString);
Use:
byte[] bytes = Base64.decodeBase64(encodedString.getBytes());
Method-2: You can Also Use Below Complete code for Encryption and decryption.
import android.util.Base64;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
public class AesUtil {
private int keySize = 256;
private int iterationCount = 1000 ;
private Cipher cipher;
private final String salt = "36e8fc9a6adf090665f459a7ad1b864d";
private final String iv = "ab00b7ea4e88500f2f0a17a7b5c7bcb1";
private final String passphrase = "ArknRQxD1YgaSFRHrjYazX7JMrlRxTERdkQx0dhENVlz";
public AesUtil() {
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw fail(e);
}
}
public String encrypt(String plaintext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, plaintext.getBytes("UTF-8"));
return Base64.encodeToString(encrypted, Base64.DEFAULT);
}
catch (UnsupportedEncodingException e) {
throw fail(e);
}
}
public String decrypt(String salt, String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
return new String(decrypted, "UTF-8");
} catch (Exception e) {
throw fail(e);
}
}
private byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));
return cipher.doFinal(bytes);
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
throw fail(e);
}
}
public SecretKey generateKey(String salt, String passphrase) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
return key;
}
catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
return null;
}
}
public static byte[] base64(String str) {
return Base64.decode(str, Base64.DEFAULT);
}
public static byte[] hex(String str) {
try {
return Hex.decodeHex(str.toCharArray());
}
catch (DecoderException e) {
throw fail(e);
}
}
private IllegalStateException fail(Exception e) {
e.printStackTrace();
return null;
}
private static IllegalStateException fail(DecoderException e) {
e.printStackTrace();
return null;
} }
After so many retries. I thought of copy pasting all the logic from sdk to my project. but seems like only one static function is not available in some of the android apache/commons framework. which is Base64.encodeBase64String()
So what I did is, I copied just one function in my project from library and recursive function call from the library exists in older framework..
So instead of using Base64.encodeBase64String() copy this function in your file and use this. This will work same.
fun encodeBase64String(binaryData: ByteArray?): String? {
return StringUtils.newStringUsAscii(
org.apache.commons.codec.binary.Base64.encodeBase64(
binaryData,
false
)
)
}
i want encrypt in Python like this java progream. than i can encrypt in python decrypt in java.
package support.security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
public final static String FILE_KEY = "qwertyuiopo";
private final String CIPHER_MODE_PADDING = "AES/CBC/PKCS7Padding";
private final String KEY_GENERATION_ALG = "PBKDF2WithHmacSHA1";
private final int HASH_ITERATIONS = 10000;
private final int KEY_LENGTH = 128;
private byte[] mSalt = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; // must save this for next time we want the key
private PBEKeySpec mKeySpec;
private SecretKeyFactory mKeyFactory = null;
private SecretKey mSKey = null;
private SecretKeySpec mSKeySpec = null;
private byte[] mIvParameter = {0xA, 1, 0xB, 5, 4, 0xF, 7, 9, 0x17, 3, 1, 6, 8, 0xC, 0xD, 91};
private IvParameterSpec mIvParameterSpec;
public AES(String key) {
mKeySpec = new PBEKeySpec(key.toCharArray(), mSalt, HASH_ITERATIONS, KEY_LENGTH);
try {
mKeyFactory = SecretKeyFactory.getInstance(KEY_GENERATION_ALG);
mSKey = mKeyFactory.generateSecret(mKeySpec);
} catch (NoSuchAlgorithmException e) {
//Log.getStackTraceString(e);
} catch (InvalidKeySpecException e) {
// Log.getStackTraceString(e);
}
byte[] skAsByteArray = mSKey.getEncoded();
mSKeySpec = new SecretKeySpec(skAsByteArray, "AES");
mIvParameterSpec = new IvParameterSpec(mIvParameter);
}
public String encrypt(byte[] plaintext) {
byte[] _plaintext = encrypt(CIPHER_MODE_PADDING, mSKeySpec, mIvParameterSpec, plaintext);
String base64_plaintext = Base64Encoder.encode(_plaintext);
return base64_plaintext;
}
public String decrypt(String base64_plaintext) {
byte[] s = Base64Decoder.decodeToBytes(base64_plaintext);
String decrypted = null;
try {
byte[] decryptBytes = decrypt(CIPHER_MODE_PADDING, mSKeySpec, mIvParameterSpec, s);//add check null by zwl when 2017.1.8
if (decryptBytes != null) {
decrypted = new String(decryptBytes, HttpContext.UTF_8);
}
} catch (UnsupportedEncodingException e) {
//Log.getStackTraceString(e);
}
return decrypted;
}
public byte[] encryptToBytes(byte[] plaintext) {
byte[] cipherText = encrypt(CIPHER_MODE_PADDING, mSKeySpec, mIvParameterSpec, plaintext);
return cipherText;
}
public byte[] decryptToBytes(byte[] plaintext) {
return decrypt(CIPHER_MODE_PADDING, mSKeySpec, mIvParameterSpec, plaintext);
}
private byte[] encrypt(String cmp, SecretKey sk, IvParameterSpec IV, byte[] msg) {
try {
Security.addProvider(new BouncyCastleProvider());
Key key = new SecretKeySpec(msg, CIPHER_MODE_PADDING);
Cipher c = Cipher.getInstance(cmp);
c.init(Cipher.ENCRYPT_MODE, sk, IV);
return c.doFinal(msg);
} catch (NoSuchAlgorithmException e) {
//Log.getStackTraceString(e);
} catch (NoSuchPaddingException e) {
// Log.getStackTraceString(e);
} catch (InvalidKeyException e) {
//Log.getStackTraceString(e);
} catch (InvalidAlgorithmParameterException e) {
// Log.getStackTraceString(e);
} catch (IllegalBlockSizeException e) {
// Log.getStackTraceString(e);
} catch (BadPaddingException e) {
// Log.getStackTraceString(e);
}
return null;
}
private byte[] decrypt(String cmp, SecretKey sk, IvParameterSpec IV, byte[] plaintext) {
try {
Cipher c = Cipher.getInstance(cmp);
c.init(Cipher.DECRYPT_MODE, sk, IV);
return c.doFinal(plaintext);
} catch (NoSuchAlgorithmException e) {
//Log.getStackTraceString(e);
} catch (NoSuchPaddingException e) {
// Log.getStackTraceString(e);
} catch (InvalidKeyException e) {
// Log.getStackTraceString(e);
} catch (InvalidAlgorithmParameterException e) {
// Log.getStackTraceString(e);
} catch (IllegalBlockSizeException e) {
// Log.getStackTraceString(e);
} catch (BadPaddingException e) {
// Log.getStackTraceString(e);
}
return null;
}
}
I tried a lot of ways but did not succeed。
key→ mSKeySpec,mIvParameterSpec,not very clear about these two values
Encrypted the results are not the same
i try this for python:
def AESEncrypt(plaintext, password):
# padding
bs = AES.block_size
padding_len = bs - len(plaintext) % bs
plaintext += chr(padding_len) * padding_len
# prepare parameters
# salt = Random.new().read(16)
salt = bytes({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF})
iv = bytes({0xA, 1, 0xB, 5, 4, 0xF, 7, 9, 0x17, 3, 1, 6, 8, 0xC, 0xD, 91})
derived = PBKDF2(password, salt, PBKDF2_ROUNDS).read(32)
key = derived
# encrypt
cipher = AES.new(key, AES.MODE_CBC, iv)
cyphertext = cipher.encrypt(plaintext)
return salt, cyphertext
Here are my encryption settings
public static final String ALGORITHM = "RSA";
public static final String CIPHER = "RSA/ECB/PKCS1Padding";
public static final String HASH_ALGORITHM = "SHA-256";
public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
public static final int KEY_SIZE = 1048;
Here is my code to encrypt
public byte[] encrypt(byte[] toEncrypt, String keyPath){
int keyLength = KEY_SIZE/8 - 11;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String toEncryptString = new String(toEncrypt,StandardCharsets.UTF_8);
String[] lines = toEncryptString.split("(?<=\\G.{" + keyLength + "})");
byte[] encryptedData = new byte[0];
try{
inputStream = new ObjectInputStream(new FileInputStream(keyPath));
final PublicKey publicKey = (PublicKey) inputStream.readObject();
final Cipher cipher = Cipher.getInstance(CIPHER);
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
if(toEncrypt.length >= keyLength){
for(String line : lines){
byteArrayOutputStream.write(cipher.doFinal(line.getBytes("UTF-8")));
}
}else{
byteArrayOutputStream.write(cipher.doFinal(toEncrypt));
}
encryptedData = byteArrayOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
byte[] cipheredData = base64Encoder(encryptedData);
System.out.println(Arrays.toString(cipheredData));
return cipheredData;
}
Here is my code to decrypt
public byte[] decrypt(byte[] toDecrypt, String keyPath) {
byte[] decypherText = base64Decoder(toDecrypt);
System.out.println(toDecrypt.length);
System.out.println(decypherText.length);
int keyLength = KEY_SIZE/8 - 11;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String toEncryptString = Arrays.toString(decypherText);
String[] lines = toEncryptString.split("(?<=\\G.{" + keyLength + "})");
byte[] decipheredData = new byte[0];
try{
inputStream = new ObjectInputStream(new FileInputStream(keyPath));
final PrivateKey privateKey = (PrivateKey) inputStream.readObject();
final Cipher cipher = Cipher.getInstance(CIPHER);
cipher.init(Cipher.DECRYPT_MODE,privateKey);
if(decypherText.length >= keyLength){
for(String line : lines){
byteArrayOutputStream.write(cipher.doFinal(line.getBytes("UTF-8")));
}
}else{
byteArrayOutputStream.write(cipher.doFinal(decypherText));
}
decipheredData = byteArrayOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(decipheredData));
return decipheredData;
}
I'm trying to encrypt a Public Key "A" with the Public Key "B". Encryption is successful, but when I try to decrypt it with the Private Key "B", it gives me that error.
The code looks fine to me, already reviewed it several times, these past 16 hours, already searched through several posts in here, and did not found a suitable answer for my problem.
Also, it already gave me BadPaddingException when decrypting. "Data must not be longer than 131 bytes". However, I'm using a Cipher with padding, so it can only decrypt data with 120 bytes. Why this error, if the Public key ciphered is splitted into blocks of 120 bytes?
Edit: before anyone else says that encrypting a Public Key is a mistery, have in your mind that it's the purpose of the project.. to have a Public Key as an ID and, as such, the need to encrypt so that no one discovers the ID of the user.
Your code doesn't make sense. You're trying to split the ciphertext on a plaintext string. It isn't there. It got removed when you split the string. In any case the data has been encrypted, so searching for a plaintext in it is futile.
You should be base64-decoding, decrypting, reading objects, and then recombining them using "(?<=\\G.{" + keyLength + "})" as a delimiter.
In fact why you're splitting in the first place and then encrypting multiple lines is a mystery.
And why you're serializing is another. Just encrypt the entire thing, without splitting, base64-encode it, and save that. When decrypting, just base64-decode it and decrypt it.
And, finally, why you're encrypting a public key at all is a complete mystery. It's PUBLIC. Not a secret.
this is the java code:
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class Main {
/**
* entry the content
*
* #param content the content need to entry
* #param password the key
* #return
*/
public static String md5Aessign(String content, String password) {
MessageDigest md;
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
kgen.init(128, random);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] byteContent = content.getBytes("GBK");
md = MessageDigest.getInstance("MD5");
md.update(byteContent);
byte[] result = cipher.doFinal(md.digest());
return parseByte2HexStr(result);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
/**
*
*
* #param buf
* #return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println("Hello World!");
String content = "Hello World!";
String key = "1234567812345678";
System.out.println(md5Aessign(content, key));
}
}
Well ,I want implement it in c#. Here is the code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace TestDes
{
class Test
{
public static string Encrypt(string toEncrypt, string key)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] temp = Encoding.GetEncoding("GBK").GetBytes(toEncrypt);
byte[] toEncryptArray = md5.ComputeHash(temp);
RijndaelManaged rDel = new RijndaelManaged();
var aes = new AesManaged();
var sha1 = new SHA1Managed();
var byteHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(key));
var truncatedHash = new byte[16];
Array.Copy(byteHash, truncatedHash, Math.Min(truncatedHash.Length, byteHash.Length));
rDel.KeySize = 128;
rDel.BlockSize = 128;
rDel.Key = truncatedHash;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform crypto = rDel.CreateEncryptor();
byte[] cryptData = crypto.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return ParseByte2HexStr(cryptData);
}
/// <summary>
///
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public static string ParseByte2HexStr(byte[] buffer)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
sb.Append(buffer[i].ToString("X2"));
}
return sb.ToString();
}
static void Main(string[] args)
{
String content = "Hello World!";
String key = "1234567812345678";
Console.WriteLine(Encrypt(content, key));
Console.ReadKey();
}
}
}
but it don't matches...
java output : C9BA133078BB8AE69FB56D2F76D5E5D17ECC29AFA9533026D2CF87C4DFAE29D9
c# output : A7280364DD9AC4A1867AAF22C049EC05C7225A807FB0E39E0BFF3047382EF901
I want the c# equals the java. platform: jdk 1.7; .net 4.0.
I have this strange issue with java IO, in combination with AES encryption.
I am writing some encrypted text to a binary file, appending \n at the end of text. Say,
my beautiful string...
look! Another of my beautiful strings...
When I read the data back, I get the following text in return with a lot of extra tabs:
my beautiful string...
look! Another of my beautiful strings...
Here is my self-contained code:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class SecurityUtil
{
public static final String ENCRYPTION_ALGORITHM = "AES";
public static final String CHARACTER_SET = "UTF-8";
private static final int BLOCKS = 128;
private static final String KEY = "SomeSortOfEncryptionKey";
public static void main (String[] args) throws IOException
{
String str = "my beautiful string...\n";
byte[] encrypt = SecurityUtil.encrypt (str);
File f = new File ("C:\\myfile.dat");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f, true));
bos.write(encrypt);
bos.flush();
bos.close();
str = "look! Another of my beautiful strings...";
encrypt = SecurityUtil.encrypt (str);
bos = new BufferedOutputStream(new FileOutputStream(f, true));
bos.write(encrypt);
bos.flush();
bos.close();
byte[] buffer = new byte[(int) f.length ()];
FileInputStream fis = new FileInputStream (f);
fis.read (buffer);
fis.close ();
String decrypt = SecurityUtil.decrypt (buffer);
System.out.println(decrypt);
}
public static byte[] encrypt (String text)
{
try
{
byte[] rawKey = getRawKey (KEY.getBytes (CHARACTER_SET));
SecretKeySpec skeySpec = new SecretKeySpec (rawKey, ENCRYPTION_ALGORITHM);
Cipher cipher = Cipher.getInstance (ENCRYPTION_ALGORITHM);
cipher.init (Cipher.ENCRYPT_MODE, skeySpec);
return cipher.doFinal (text.getBytes (CHARACTER_SET));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace ();
}
catch (IllegalBlockSizeException e)
{
e.printStackTrace ();
}
catch (BadPaddingException e)
{
e.printStackTrace ();
}
catch (InvalidKeyException e)
{
e.printStackTrace ();
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace ();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace ();
}
return null;
}
public static String decrypt (byte[] data)
{
try
{
byte[] rawKey = getRawKey (KEY.getBytes (CHARACTER_SET));
SecretKeySpec skeySpec = new SecretKeySpec (rawKey, ENCRYPTION_ALGORITHM);
Cipher cipher = Cipher.getInstance (ENCRYPTION_ALGORITHM);
cipher.init (Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal (data);
return new String (decrypted);
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace ();
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace ();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace ();
}
catch (InvalidKeyException e)
{
e.printStackTrace ();
}
catch (IllegalBlockSizeException e)
{
e.printStackTrace ();
}
catch (BadPaddingException e)
{
e.printStackTrace ();
}
return null;
}
private static byte[] getRawKey (byte[] seed)
{
try
{
KeyGenerator kgen = KeyGenerator.getInstance (ENCRYPTION_ALGORITHM);
SecureRandom sr = SecureRandom.getInstance ("SHA1PRNG");
sr.setSeed (seed);
kgen.init (BLOCKS, sr);
SecretKey skey = kgen.generateKey ();
byte[] raw = skey.getEncoded ();
return raw;
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace ();
}
return null;
}
}
Here is the console output (with extra spaces):
my beautiful string...
look! Another of my beautiful strings...
What am I doing wrong?
Ok! I got it. You cannot just append the encrypted text to a file. One way of solving this is extracting existing text from the file, append the new text, encrypt and write in the file again.
This doesn't seem to be a good solution, but in my case, where there is little text in a file, this can work.