Android: DSA signatures - sign and verify - android

I am having problems verifying a signature which I've just created. After signing I first convert the signature to text using Base64 and as a test I wanted to verify that I can decode the Base64 and verify the signature. This fails. Here is some code without the error handling.
I have my keypair:
DSAPrivateKey privateKey = (DSAPrivateKey) keyPair.getPrivate();
DSAPublicKey publicKey = (DSAPublicKey) keyPair.getPublic();
Now I sign some text and print to log output - it seems fine:
String text = "test";
Signature signer = null;
signer = Signature.getInstance(privateKey.getAlgorithm());
SignedObject signedObject = null;
signedObject = new SignedObject(text, privateKey, signer);
String print_signature = Base64.encodeToString(signedObject.getSignature(), Base64.DEFAULT);
System.out.println("Base64 Signature: " + print_signature);
Now I verify the signature using the SignedObject object created above and not the Base64. This is successful:
Signature verifier = null;
verifier = Signature.getInstance(publicKey.getAlgorithm());
boolean b = signedObject.verify(publicKey, verifier));
For my app I will only have the public certificate of the signer and the Base64 encoded string so I must verify the signature using these parameters only and can therefore AFAIK not use a SignedObject object. I used the Signature object:
Signature verifier1 = null;
verifier1 = Signature.getInstance(publicKey.getAlgorithm());
verifier1.initVerify(publicKey);
verifier1.update(text.getBytes()); // sorry I forgot this in original posting
byte[] sig1 = Base64.decode(print_signature, Base64.DEFAULT);
b = verifier1.verify(sig1));
This verification always fails (b = false).

Why are you using the SignedObject in the first place? What does it buy you? As for the verify failure, make sure that you get the same bytes after transmission/receiving. Are you sending/receiving in the same encoding? Is someone modifying the string?

Related

How to encrypt the Key and IV which used in AES Encryption Model in android App

I have android application which has payment gateway and another services.Iam using AES Model to encrypt and decrypt data between the app and the server.Iam using KEY and IV constants which stored in android class. My problem is how to encrypt these constants ( IV and Key) in the android application to prevent any attacker to make decompile for the APK file and show these constants.
You have to Encrypt the Key with a RSA Public Key and only the Server knows the privatekey for this public key and can decrypt it.
You decrypt the AES Key with the private key on the serverside and use the decrypted AES Key to decrypt your original message.
//Edit
This is an example for the Java Code in Android Studio. My RSA Public key is stored in the shared preferences.
When the app is installed it makes a call to a Server, where a RSA Key pair is produced, both keys are saved in a Database and the Public Key is sent to the Device and saved in the shared preferences. Whenever something Needs to be Encrypted the stored Public Key is created and used for Encryption and only the Server knows the private key.
byte[] ENCRYPTED_AES_KEY_IN_BYTE = null;
String ENCRYPTED_AES_KEY;
cipher = null;
cipher = Cipher.getInstance("RSA/NONE/OAEPwithSHA-1andMGF1Padding");
// Get the shared preferences where the public key is stored
// SharedPreferences preferences = getApplicationContext().getSharedPreferences(preferences,Context.MODE_PRIVATE);
// get the Publickey stored as string in the shared preferences
String stringkey = preferences.getString(PUBLICKEY,"");
// create a public RSA Key from the stored key
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(stringkey,Base64.DEFAULT));
KeyFactory keyFactory;
PublicKey key =null;
keyFactory = KeyFactory.getInstance("RSA");
key = keyFactory.generatePublic(spec);
//Encrypt the AES key with the RSA public key
cipher.init(Cipher.ENCRYPT_MODE, key);
ENCRYPTED_AES_KEY_IN_BYTES = AES_KEY.getEncoded();
ENCRYPTED_AES_KEY_IN_BYTE = cipher.doFinal(ENCRYPTED_AES_KEY_IN_BYTE);
ENCRYPTED_AES_KEY = Base64.encodeToString(ENCRYPTED_AES_KEY_IN_BYTE,Base64.DEFAULT);
//ENCRYPTED_AES_KEY is now the Encrypted AES Key as string
// EDIT #2
Create a RSA KEY pair at the server
$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS8);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
extract($rsa->createKey());
$publickey = str_replace("-----BEGIN PUBLIC KEY-----\r\n","",$publickey);
$publickey = str_replace("-----END PUBLIC KEY-----","",$publickey);
$privatekey = str_replace("-----BEGIN PRIVATE KEY-----\r\n","",$privatekey);
$privatekey = str_replace( "-----END PRIVATE KEY-----","",$privatekey);
the privatekey is saved to a Database and the Publickey is sent to the Client to Encrypt data.
To Decrypt the Data on the Serverside again
$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS8);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setEncryptionMode( CRYPT_RSA_ENCRYPTION_OAEP);
$IV = base64_decode($IV);
$AESkey = base64_decode($AESkey);
$rsa->loadKey($privatekey);
$AESkey = $rsa->decrypt($AESkey);
// replace empty spaces with a + , this is something which can happen when you use a http request
$encrypteddata = str_replace(" ", "+", $encrypteddata);
$encrypteddata = base64_decode($encrypteddata);
$method = "AES-256-CBC";
$decrypteddata = openssl_decrypt($encrypteddata, $method, $AESkey, OPENSSL_RAW_DATA,$IV);
In this Code is not included how you store the privatekey in a Database and how you get it back from the Database.

Save data on KeyStore and retrieve it using keychain

I want to save some of my sensitive data (string) in keyStore. I found that keyStore only accepts secretKey objects. But, I'm not able to store it and and retreive it later using keyChain callback by using the alias name of the secretKey
Any help will be appreciated..!
I think you are looking something like MD5. An MD5 hash is created by taking a string of an any length and encoding it into a 128-bit fingerprint. Encoding the same string using the MD5 algorithm will always result in the same 128-bit hash output. MD5 hashes are commonly used with smaller strings when storing passwords, credit card numbers or other sensitive data in databases such as the popular MySQL. This tool provides a quick and easy way to encode an MD5 hash from a simple string of up to 256 characters in length.
MD5 hashes are also used to ensure the data integrity of files. Because the MD5 hash algorithm always produces the same output for the same given input, users can compare a hash of the source file with a newly created hash of the destination file to check that it is intact and unmodified.
Hashing String with MD5:
public class JavaMD5Hash {
public static void main(String[] args) {
String password = "MyPassword123";
System.out.println("MD5 in hex: " + md5(password));
System.out.println("MD5 in hex: " + md5(null));
//= d41d8cd98f00b204e9800998ecf8427e
System.out.println("MD5 in hex: "
+ md5("The quick brown fox jumps over the lazy dog"));
//= 9e107d9d372bb6826bd81d3542a419d6
}
public static String md5(String input) {
String md5 = null;
if(null == input) return null;
try {
//Create MessageDigest object for MD5
MessageDigest digest = MessageDigest.getInstance("MD5");
//Update input string in message digest
digest.update(input.getBytes(), 0, input.length());
//Converts message digest value in base 16 (hex)
md5 = new BigInteger(1, digest.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
}
referance :
http://viralpatel.net/blogs/java-md5-hashing-salting-password/
https://www.mkyong.com/java/java-md5-hashing-example/
http://www.asjava.com/core-java/java-md5-example/
you can use shared preferance which is very easy to handle also.
https://developer.android.com/training/basics/data-storage/shared-preferences.html
Android Shared preferences example

Encryption & Decryption algorithm

I am working on mobile product. We are using the data in xml document. In order to keep our data secure we need an encryption algorithm(but we don't want the existing algorithm to import)
Can u give me some steps to encrypt the data.(if code example is most welcome).
To be more secure, you have to do with your own secret key. Try to use this code
KeyStore ks = KeyStore.getInstance();
// get the names of all keys created by our app
String[] keyNames = ks.saw("");
// store a symmetric key in the keystore
SecretKey key = Crypto.generateKey();
boolean success = ks.put("secretKey1", key.getEncoded());
// check if operation succeeded and get error code if not
if (!success) {
int errorCode = ks.getLastError();
throw new RuntimeException("Keystore error: " + errorCode);
}
// get a key from the keystore
byte[] keyBytes = ks.get("secretKey1");
SecretKey key = new SecretKeySpec(keyBytes, "AES");
// delete a key
boolean success = ks.delete("secretKey1");
If you want to develop your own encryption scheme, be prepared to embark on a research project. You can use any of standard encryption algorithms like AES/DES etc, with your private keys that are sufficiently long and difficult to crack.
public string PassEncrypt(string Password)
{
// Encrypting the password entered by User
// ======================================================
MD5 md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(Password));
byte[] result = md5.Hash;
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
strBuilder.Append(result[i].ToString("x2"));
}
return strBuilder.ToString();
// ======================================================
}
OR
You may refer on this links :
developer.motorala.com
codereview.stackexchange.com
android snippets
java-tips.org

How to verify a public key in string/byte[] format against certificates in bks store

I want to verify if a certificate with a certain public key exits in android keystore or not.I have key which is holded in a string.How do I verify if the corresponding certificate is present in keystore.
When checked the apis i found certificate.verify(mykey); is the only option.but mykey sholud be of type PublicKey and I have it in string.
String is 0r1wxn7wIXJuS/hDnDvectD2VTmel9akk8awIWAXIRo= .....this is a hash of public key..i have to return back the certficate corresponding to this key.
Can anyone help me ?
Can anyone help me ?
Regards
kozlov
KeyStore store = ... ;
byte[] target = ... ; // Base-64 decode your string.
MessageDigest digest = MessageDigest.getInstance(algorithm);
Enumeration<String> aliases = store.aliases();
while(aliases.hasMoreElements()) {
String alias = aliases.nextElement();
Certificate c = store.getCertificate(alias);
if (c == null)
continue;
PublicKey pub = c.getPublicKey();
byte[] hash = digest.digest(pub.getEncoded());
if (MessageDigest.isEqual(hash, target)) {
// Certificate "c" is a match.
}
}

How to Generate HMAC MD5 In Android?

I am new in this Field!I have this Message and Key also i want HMAC MD5 using this two so how it is possible if possible then give some example or sample code of this.The Given link display the overall functionality i want such kind of code.Please help me.
Messgae = POSTuserMon,28Jun201010:18:33GMT7FF4471B-13C0-5A9F-BB7B-7309F1AB7F08
key = d6fc3a4a06ed55d24fecde188aaa9161
Link = http://hash.online-convert.com/md5-generator
Here are working codes.
Generated result is same as Link = http://hash.online-convert.com/md5-generator
public String calcHmac(String src) throws Exception {
String key = "d6fc3a4a06ed55d24fecde188aaa9161";
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec sk = new SecretKeySpec(key.getBytes(),mac.getAlgorithm());
mac.init(sk);
byte[] result = mac.doFinal(src.getBytes());
return Base64.encodeToString(result ,Base64.URL_SAFE);
}
Look at the javax.crypto.Mac class. Try Mac.getInstance("HmacMD5"); and then use the init method with your key and then use the update and doFinal methods just as you would with a MessageDigest object.

Categories

Resources