How to implement AES technique for cryptography [closed] - android

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
i want to implement the AES techniques in java for android application, i search out many tutorial for this but that was not super. SO please help in this regard, if some body know the code, for Implementing AES techniques for ANDROID APPLICATION.
thanks in adnvance.

Aes ecrpt class
package com.d.social.network;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MCrypt {
private String iv = "fedcba9876543210";//Dummy iv (CHANGE IT!)
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
private String SecretKey = "0123456789abcdef";//Dummy secretKey (CHANGE IT!)
public MCrypt()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty string");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
if( decrypted.length > 0)
{
int trim = 0;
for( int i = decrypted.length - 1; i >= 0; i-- ) if( decrypted[i] == 0 ) trim++;
if( trim > 0 )
{
byte[] newArray = new byte[decrypted.length - trim];
System.arraycopy(decrypted, 0, newArray, 0, decrypted.length - trim);
decrypted = newArray;
}
}
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 16;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
}
To use it
MCrypt mcrypt = new MCrypt();
MCrypt.bytesToHex( mcrypt.encrypt("hello"));

Related

Cipher functions:EVP_DecryptFinal_ex:DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH

Im trying to implement AES in an Android application. The server is a PHP server.
This is the AES code :
public class AES{
private String SecretKey = "89432hjfsd891787";
private String iv = "fedcba9876543210";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public AES()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty string");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 16;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++) {
source += paddingChar;
}
return source;
}
}
I get an error while decrypting the incoming string : Cipher functions:EVP_DecryptFinal_ex:DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
How do i go about this?
Manually padding the String representation of the plaintext with spaces is not a good padding mechanism. Instead, you should use AES/CBC/PKCS5Padding which will handle the padding as prescribed in PKCS #5/#7.
You should also:
generate a unique IV per encryption operation rather than re-using the same value for all messages
Use an authenticated mode of operation (GCM, HMAC/SHA-256 MAC over cipher text, etc.)
Store the key in hexadecimal representation of the raw bytes rather than an ASCII/UTF-8 String encoding (not specified in your code)
Encode the cipher text in Base64 or Hex before serializing/transmitting. Encoding errors can contribute to padding exceptions during decryption.

Android Bluetooth input stream not reading full array

I'm creating an app to read string values over Bluetooth serial port. My data receiving but in two parts. If I send $F00,A,B,0,M# via bluetooth it only reads $ in first part and F00,A,B,0,M# in next part. I provided my code here. Please do correct me if I'm wrong.
InputStream inputStream=null;
int avilableBytes=0;
public ConnectedThread(BluetoothSocket socket){
InputStream temp=null;
try{
temp=socket.getInputStream();
}catch (IOException e){
e.printStackTrace();
}
inputStream=temp;
}
public void run() {
try{
int bytes;
while (true){
try{
avilableBytes=inputStream.available();
if (avilableBytes>0){
byte[] buffer=new byte[avilableBytes];
bytes=inputStream.read(buffer);
final String readMessage=new String(buffer,0,bytes);
bt_handler.obtainMessage(handlerState,bytes,-1,readMessage).sendToTarget();
Log.d("PRAVEEN",readMessage);
}
}catch (IOException e){
e.printStackTrace();
}
}
}catch (Exception e){
e.printStackTrace();
}
}
Data are like stream bytes and can not be processed immediately when it comes with a few bytes. Data will not come all at once as a single packet. You have to use the other byte[] buffer (MainBuffer) in which you will gradually save incoming byte and move the index in that buffer. Then, from time to time (e.g. in the timer once per second) take data from the main buffer and processed it. By default you must implement some data frame with a separator (eg. Data * data * data * - Many ways to do it good or bad). I dealt with this in .net via Xamarin, but just as an example it may be helpfull :
update example, format
In ConnectedThread :
public override void Run()
{
while (true)
{
try
{
int readBytes = 0;
lock (InternaldataReadLock)
{
readBytes = clientSocketInStream.Read(InternaldataRead, 0, InternaldataRead.Length);
Array.Copy(InternaldataRead, TempdataRead, readBytes);
}
if (readBytes > 0)
{
lock (dataReadLock)
{
dataRead = new byte[readBytes];
for (int i = 0; i < readBytes; i++)
{
dataRead[i] = TempdataRead[i];
}
}
Bundle dataBundle = new Bundle();
dataBundle.PutByteArray("Data", dataRead);
Message message = btlManager.sourceHandler.ObtainMessage();
message.What = 1;
message.Data = dataBundle;
btlManager.sourceHandler.SendMessage(message);
}
}
catch (System.Exception e)
{
btlManager.btlState = BTLService.BTLState.Nothing;
}
}
}
In BTLHandler :
public override void HandleMessage(Message msg)
{
switch (msg.What)
{
case 1:
{
byte[] data = msg.Data != null ? msg.Data.GetByteArray("Data") : new byte[0];
btlService.BTLReceiveData(data);
}
break;
}
}
public void BTLReceiveData(byte[] data)
{
lock (dataReadLock)
{
for (int i = 0; i < data.Length; i++)
{
dataRead[dataReadWriteCursor] = data[i];
dataReadWriteCursor++;
}
}
}
In Timer :
int tmpWriteCursor = dataReadWriteCursor;
int tmpReadCursor = dataReadReadCursor;
lock (dataReadLock)
{
int newBytes = dataReadWriteCursor - dataReadReadCursor;
for (int i = 0; i < newBytes; i++)
{
dataReadMain[dataReadReadCursor] = dataRead[dataReadReadCursor++];
}
}
bool odradkovani = false;
string tmpRadek = "";
int lastLineIndex = 0;
List<string> list = new List<string>();
for (int i = LastWriteLineIndex; i < tmpWriteCursor; i++)
{
if (dataReadMain[i] >= 32 && dataReadMain[i] <= 255)
{
tmpRadek += (char)dataReadMain[i];
}
else if (dataReadMain[i] == 13) odradkovani = true;
else if (dataReadMain[i] == 10)
{
if (odradkovani)
{
odradkovani = false;
list.Add(Utils.GetFormatedDateTime(DateTime.Now) + " " + tmpRadek);
tmpRadek = "";
lastLineIndex = i + 1;
}
}
else
{
tmpRadek += "?" + dataReadMain[i].ToString() + "?";
}
}
WriteDataToLog(list);
LastWriteLineIndex = lastLineIndex;

Converting a string sent via SMS into RSA Public/Private key in android

I've been working on it for several days but without success, I' m doing SMS encryption in android using RSA encryption, the problem is how can I convert a String to public key and use it for encryption, I'm sending the publicKey converted into String via SMS but I'm not able to get the key back.
This is how my algorithm works but when I send "puk" as a string via Sms and make encryption it doesn't work anymore!!! plz help me . . .
private final static String RSA = "RSA";
public static PublicKey uk;
public static PrivateKey rk;
public static String puk;
public static void generateKey() throws Exception
{
KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA);
gen.initialize(128, new SecureRandom());
KeyPair keyPair = gen.generateKeyPair();
uk = keyPair.getPublic();
rk = keyPair.getPrivate();
puk = uk.toString();
}
private static byte[] encrypt(String text, PublicKey pubRSA) throws Exception
{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes());
}
public final static String encrypt(String text)
{
try {
return byte2hex(encrypt(text, uk));
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public final static String decrypt(String data)
{
try{
String text = new String(decrypt(hex2byte(data.getBytes())));
return text+" OK";
}
catch (Exception e)
{
return "Error: "+e;
}
}
private static byte[] decrypt(byte[] src) throws Exception
{
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, rk);
return cipher.doFinal(src);
}
public static String byte2hex(byte[] b)
{
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n ++)
{
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1)
hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
public static byte[] hex2byte(byte[] b)
{
if ((b.length % 2) != 0)
throw new IllegalArgumentException("hello");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2)
{
String item = new String(b, n, 2);
b2[n/2] = (byte)Integer.parseInt(item, 16);
}
return b2;
}

Solving StringIndexOutOfBoundsException

I received a crash report, which is about java.lang.StringIndexOutOfBoundsException in ZhuangDictActivity$SearchDicAsyncTask.doInBackground
Here is the ZhuangDictActivity$SearchDicAsyncTask.doInBackground:
private class SearchDicAsyncTask extends AsyncTask<String, Integer, String> {
private byte searchStatus;
#Override
protected String doInBackground(String... params) {
if (params[0].length() > 0) {
word = params[0].trim();
long[] index = null;
FileAccessor in = null;
DictZipInputStream din = null;
try {
char key = GB2Alpha.Char2Alpha(word.charAt(0));
tableName = DatabaseHelper.transTableName(key);
index = databaseHelper.queryTable(tableName, word);
if (index != null) {
in = new FileAccessor(new File(dictFileName), "r");
byte[] bytes = new byte[(int) index[1]];
if (isDZDict) {
din = new DictZipInputStream(in);
DictZipHeader h = din.readHeader();
int idx = (int) index[0] / h.getChunkLength();
int off = (int) index[0] % h.getChunkLength();
long pos = h.getOffsets()[idx];
in.seek(pos);
byte[] b = new byte[off + (int) index[1]];
din.readFully(b);
System.arraycopy(b, off, bytes, 0, (int) index[1]);
} else {
in.seek(index[0]);
in.read(bytes);
}
wordDefinition = new String(bytes, "UTF-8");
} else {
searchStatus = 0;
return null;
}
} catch (FileNotFoundException ffe) {
searchStatus = 1;
return null;
} catch (IOException ex) {
ex.printStackTrace();
searchStatus = 2;
return null;
} finally {
try {
if (din != null)
din.close();
if (in != null)
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
return wordDefinition;
}
}
The complete code is available here.
I have limited knowledge in Java and Android development. How should I solve this? I intended to post the complete stack traces but stackoverflow do not allow me to do so because it stated my question has too many code. Anyway, the line which is causing the problem is char key = GB2Alpha.Char2Alpha(word.charAt(0));.
It is possible that your string contains only white spaces. meaning it passed the condition:
if (params[0].length() > 0)
But when you call trim(), these are removed, resulting in an empty stream and an "IndexOutOfBoundsException" exception being thrown when you execute:
word.charAt(0)
EDIT
This is not the reason. After a test, when trim is called on a String with only whitespaces, the String remains unchanged.

Android check download successful

For downloading stuff I work with the apache classes HTTPResponse HTTPClient etc.
I check for a valid download like this:
entity.writeTo(new FileOutputStream(outfile));
if(outfile.length()!=entity.getContentLength()){
long fileLength = outfile.length();
outfile.delete();
throw new Exception("Incomplete download, "+fileLength+"/"
+entity.getContentLength()+" bytes downloaded");
}
But it seems that the exception is never triggered. How to properly handle this? Is entity.getContentLength the length of the file on server or the amount of data received?
The file request should always come with a MD5 checksum. If you have an MD5 header then all you need to do is check that against the files generated MD5. Then your done, its better to do it this way as you can have a file with the same number of bytes but one byte gets garbled in transmission.
entity.writeTo(new FileOutputStream(outfile));
String md5 = response.getHeaders("Content-MD5")[0].getValue();
byte[] b64 = Base64.decode(md5, Base64.DEFAULT);
String sB64 = IntegrityUtils.toASCII(b64, 0, b64.length);
if (outfile.exists()) {
String orgMd5 = null;
try {
orgMd5 = IntegrityUtils.getMD5Checksum(outfile);
} catch (Exception e) {
Log.d(TAG,"Exception in file hex...");
}
if (orgMd5 != null && orgMd5.equals(sB64)) {
Log.d(TAG,"MD5 is equal to files MD5");
} else {
Log.d(TAG,"MD5 does not equal files MD5");
}
}
Add this class to your project:
public class IntegrityUtils {
public static String toASCII(byte b[], int start, int length) {
StringBuffer asciiString = new StringBuffer();
for (int i = start; i < (length + start); i++) {
// exclude nulls from the ASCII representation
if (b[i] != (byte) 0x00) {
asciiString.append((char) b[i]);
}
}
return asciiString.toString();
}
public static String getMD5Checksum(File file) throws Exception {
byte[] b = createChecksum(file);
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public static byte[] createChecksum(File file) throws Exception {
InputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
return complete.digest();
}
}

Categories

Resources