I'm currently trying to develop an encryption app for Android using ECDH and BouncyCastle. So far what I've implemented is Public and Private Key generation on the application as per the code below.
My next task is to send the public keys over SMS. I would like to find out what methods can be used to get the job done. Currently I'm trying it out by assigning the generated keys to a string then I'm sending the string out but I'm still unable to get it to work properly.
Any assistance would be greatly appreciated
Thanks and Happy Holidays!
try
{
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "SC");
//Define the Elliptic Curve Field, Points A and B
EllipticCurve curve = new EllipticCurve(new ECFieldFp(Presets.CurveQ),Presets.PointA,Presets.PointB);
//Define the points on the Elliptic Curve
ECParameterSpec ecSpec = new ECParameterSpec(
curve,
ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n
1); // h
//Generate the random point on the Elliptic Curve
g.initialize(ecSpec, new SecureRandom());
//Generate Private Key for User A
KeyPair aKeyPair = g.generateKeyPair();
aKeyAgree = KeyAgreement.getInstance("ECDH", "SC");
aKeyAgree.init(aKeyPair.getPrivate());
//Save Personal Keys
Presets.myPrivateKey = aKeyPair.getPrivate().getEncoded().toString();
Presets.myPublicKey = aKeyPair.getPublic().getEncoded().toString();
I managed to find out what I was doing wrongly.
The output I was getting from
Presets.myPublicKey = aKeyPair.getPublic().getEncoded().toString();
was something along the lines of [#B1ef9157 which could not be sent over SMS like I hoped for.
Java: Syntax and meaning behind "[B#1ef9157"? Binary/Address?
Instead I did this
byte[] pubEnc = aKeyPair.getPublic().getEncoded();
String s = Base64.encodeBytes(pubEnc);
making use of the Base64 encoder from http://iharder.sourceforge.net/current/java/base64/
and now I am able to successfully send the string over sms.
Thanks Craigy!
Related
I got App api_id, App api_hash and Production configuration from telegram.org, I need to use from this method messages.sendMessage for Sends a text message to a specific number phone's telegram(for example: +1888888). How can I use from this method. Is there any a simple sample?
I suggest you using a top-layer library over MTProto to make things easier. For example you can use Telethon. You should use SendMessageRequest in order to send message. After creating a client you can call it like this (in newest version of Telethon the phone number is resolved automatically):
from telethon.tl.functions.messages import SendMessageRequest
client(SendMessageRequest('phone_number', 'hello'))
If you're using TDLib, you may use this function (taken from here) or a similar one:
private static void sendMessage(long chatId, String message) {
// initialize reply markup just for testing
TdApi.InlineKeyboardButton[] row = {new TdApi.InlineKeyboardButton("https://telegram.org?1", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?2", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?3", new TdApi.InlineKeyboardButtonTypeUrl())};
TdApi.ReplyMarkup replyMarkup = new TdApi.ReplyMarkupInlineKeyboard(new TdApi.InlineKeyboardButton[][]{row, row, row});
TdApi.InputMessageContent content = new TdApi.InputMessageText(new TdApi.FormattedText(message, null), false, true);
client.send(new TdApi.SendMessage(chatId, 0, false, false, replyMarkup, content), defaultHandler);
}
Don't forget that, you need to add each phone number to user's Telegram contacts first to get the chatId. It can be achieved by passing an array of phone numbers to this function:
---functions---
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts
I need an end to encrypt different strings and related decryptions after user authenticate using fingerprint scanner.
Following this project (https://github.com/StylingAndroid/UserIdentity/tree/Part1) and changed "tryEncrypt" method like below:
private boolean tryEncrypt(Cipher cipher) {
try {
cipher.doFinal(SECRET_BYTES);
String one = "augusto";
String two = "test#gmail.com";
String three = "3333333331";
byte[] oneEnc = cipher.doFinal(one.getBytes());
byte[] twoEnc = cipher.doFinal(one.getBytes());
byte[] threeEnc = cipher.doFinal(one.getBytes());
Log.d("test", "oneEnc: " + Base64.encodeToString(oneEnc,0));
Log.d("test", "twoEnc: " + Base64.encodeToString(twoEnc,0));
Log.d("test", "threeEnc: " + Base64.encodeToString(threeEnc,0));
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
I'm getting this error:
java.lang.IllegalStateException: IV has already been used. Reusing IV in encryption mode violates security best practices.
What is the correct way on how to do it?
Thanks
*******************UPDATE:*****************************
To help others to get solve this problem I used this library and worked like charm:
https://github.com/Mauin/RxFingerprint
You have a problem because your are using a single instance of the Cipher for multiple encryptions (dofinal). You are using a single vector initialization (IV).
Take a look on an option of how to initialize a cipher.
SecureRandom r = new SecureRandom();
byte[] ivBytes = new byte[16];
r.nextBytes(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
As you can see, you need to specify the initialization vector. The initialization vector can not be repeated to guarantee that the encryption works.
In your scenario, you probably gonna need to perform a new initialization.
*Ps: It's also possible to use the Cipher initialization without the IvParameterSpec. In this scenario, the class will generate one for you. However, I believe that you need to perform a initialization per DoFinal to guarantee some randomness.
To help others to get solve this problem I used this library that worked like charm:
https://github.com/Mauin/RxFingerprint
I want to append a line of text to an existing Azure cloud block blob from an Android device.
In VB.Net I would AcquireLease, getBlockBlobReference, DownloadToFile, add the line on the local files system, UploadToFile, ReleaseLease . Simple and secure, if a bit long-winded.
In Android, it looks a little more tricky. At the moment, my best solution is this:
CloudBlockBlob blob1=container.getBlockBlobReference(chosenOne+".txt");
String proposedLeaseId1 = UUID.randomUUID().toString();
OperationContext operationContext1 = new OperationContext();
blob1.acquireLease(15, proposedLeaseId1, null /*access condition*/,null/* BlobRequestOptions */, operationContext1);
AccessCondition condition = new AccessCondition();
condition.setLeaseID(proposedLeaseId1);
BlobInputStream blobIn = blob1.openInputStream();
blob1.downloadAttributes();
long blobLengthToUse = blob1.getProperties().getLength();
byte[] result = new byte[(int) blobLengthToUse];
blob1.downloadToByteArray(result,0);
blobIn.close();
CloudBlockBlob blob1 = container.getBlockBlobReference(chosenOne+".txt");
String proposedLeaseId1 = UUID.randomUUID().toString();
OperationContext operationContext1 = new OperationContext();
blob1.acquireLease(15, proposedLeaseId1, null /*access condition*/,null/* BlobRequestOptions */, operationContext1);
AccessCondition condition = new AccessCondition();
condition.setLeaseID(proposedLeaseId1);
BlobInputStream blobIn = blob1.openInputStream();
blob1.downloadAttributes();
long blobLengthToUse = blob1.getProperties().getLength();
byte[] result = new byte[(int) blobLengthToUse];
blob1.downloadToByteArray(result,0);
blobIn.close();
blob1.deleteIfExists(DeleteSnapshotsOption.NONE,condition, null, operationContext1);
BlobOutputStream blobOut = blob1.openOutputStream();
//this is a byte by byte write ...
//which is fine ... but no use if you want to replace ...
/*int next = blobIn.read();
while (next != -1) {
blobOut.write(next);
next = blobIn.read();
}*/
blobOut.write(result);
String strTemp="This is just a test string";
blobOut.write(strTemp.getBytes());
blobOut.close();
Apart from being extremely long-winded, I am concerned that as soon as I delete the blob, the lease will go and that I may hit integrity issues. I would appreciate any help in making this code simpler and more secure. I know that Microsoft are planning to introduce append blobs in 3Q 2015, but I want to implement this now.
You can call PutBlock to upload the appended content (the maximum size of each block is 4MB, so please split the appended content into blocks if required), and then call PutBlockList on this blob by passing in the previously committed blocks plus and newly appended blocks.
I am able to generate Public key and Private key using spongy castle in Android by using the following code
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
ECGenParameterSpec ecSpecCurve163k1 = new ECGenParameterSpec("sect163r2"); // Curve: B-163
keyGen.initialize(ecSpecCurve163k1);
aKeyPair = keyGen.generateKeyPair();
String pubStr = Crypto.base64Encode(aKeyPair.getPublic().getEncoded());
String privStr = Crypto.base64Encode(aKeyPair.getPrivate().getEncoded());
I get Affine coordinates by using the following code
PublicKey otherKey // key generated by the code above
ECPublicKey ecPubKey = (ECPublicKey) otherKey;
Log.d("public key Wx", ecPubKey.getW().getAffineX().toString(16));
Log.d("public key Wy", ecPubKey.getW().getAffineY().toString(16));
I am trying to get the projective coordinates for the above coordinates by using spongy castle. Is there any way to get it?
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.