Error While trying to stream encrypted video using exoplayer - android

I have been trying to stream encrypted video on my server using exoplayer.
I figured out everything about the custom data source and it is streaming other online videos which are not encrypted but when I am trying to decrypt the video I am getting an error
I only know the password string (Which is "abc123" I also have md5 of this)and I have no idea how should I exactly convert it to the key and then use it with my cipher
Error 1) When I am using password string as the key I am getting unsupported key size error,
2) When I am using md5 as key I am getting UnrecognizedInputFormatException
String sb="abc123";
byte []b=sb.getBytes();
mSecretKeySpec = new SecretKeySpec(b,"AES");
mIvParameterSpec = new IvParameterSpec("abc123".getBytes());
try {
mCipher = Cipher.getInstance("AES/CBC/NoPadding");
mCipher.init(Cipher.DECRYPT_MODE, mSecretKeySpec,mIvParameterSpec);
} catch (Exception e) {
System.out.println(e.getMessage()+e.getCause()+"fuckeddd");
e.printStackTrace();
}

“abc123” is not a valid encryption key. An encryption key is a 16 byte binary value.

Related

convert binary to file p12 in Android

I get in one api a certificate digital with this value so:
response api imagen
I need convert this value to a physical file on Android device any folder how extension .p12
for after upload from the app.
finally read the file with next function FileInputStream:
try {
KeyStore p12 = KeyStore.getInstance("pkcs12");
p12.load(new FileInputStream(filepath), etPassword.getText().toString().toCharArray());
} catch (Exception e) {
}
any help thank you very much

Error "Malformed content." in Signature Verification

I want to verify my signature . my signature is a byte array. I use spongy castle
I get error "org.spongycastle.cms.CMSException: Malformed content."
this is my code:
String base64 = Base64.toBase64String(signedchallenge);
CMSSignedData cms = new CMSSignedData(Base64.decode(base64));
Store store = cms.getCertificates();
SignerInformationStore signers = cms.getSignerInfos();
Collection c = signers.getSigners();
I get error in line " CMSSignedData cms = new CMSSignedData(Base64.decode(base64));"
also I used this method for signed challenge generation. It did in smart cart
Signature signature=Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1,false);
signature.init(thePrivateKey,Signature.MODE_SIGN);
signLength=signature.sign(buffer,(short)(ISO7816.OFFSET_CDATA & 0xFF), inputlength, buffer, (short)(0));
apdu.setOutgoingAndSend((short)0,signLength);
According to javacard documentation
ALG_RSA_SHA_PKCS1 generates a 20-byte SHA digest, pads the digest according to the PKCS#1 (v1.5) scheme, and encrypts it using RSA
To verify the signature in Android side use this code
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);
sig.update(challenge);
boolean verifies = sig.verify(signedchallenge);
Where signedchallenge is the signature available on buffer from (short)(ISO7816.OFFSET_CDATA & 0xFF) to signLength and challenge is the original data to sign

aes-256-cbc encryption and decryption

I am encrypting an audio file using crypto npm module in node.js and trying to decrypt it in the android side using the same algorithm and the key.
The encryption code is :
encyption parameters
var crypto = require('crypto'),
algorithm = 'aes-256-cbc',
password = 'somepassword'; //encyption parameters
encryption function
function encrypt(buffer) {
var cipher = crypto.createCipher(algorithm, password);
var crypted = Buffer.concat([cipher.update(buffer), cipher.final()]);
return crypted;
}
Now,for Decryption , we need to use some IV(Initialisation Vector) and as research says not to use same IV for any two files.
So, I just want to know now how customized IV can be set and random or separate IVs can be generated for each file in node.js using crypto or any other module during encryption.
It will be great if someone can help me out in this.
to create the IV, use the following command to get 16 random bytes:
var iv = crypto.randomBytes(16)
then, when creating the cipher, change
var cipher = crypto.createCipher(algorithm, password);
to
var cipher = crypto.createCipheriv(algorithm, password, iv);
The IV will not be attached to the resulting ciphertext, so you will need to send it separately to the android side (it can be sent in plaintext).

Is it possible to access a runtime decrypted file in android?

I want to decrypt a file stored at my app's res folder. This file is distributed with the app, and I'm trying to decrypt it only once during app start.
So far, I've found some answers (this one, for instance) about how to write the decrypted file into sdcard, but won't that file be available to malicious access at the sdcard?
I wish I could write the CipherInputStream into a java.io.InputStream, so I could use it without writing any decrypted data to disk. Is it possible?
I think you want something like this
private InputStream getDecodedInputStream (InputStream eis) {
Cipher cipher = Cipher.getInstance("your cipher definition");
cipher.init(Cipher.DECRYPT_MODE, "your keySpec", new IvParameterSpec("your IV parameter spec"));
InputStream decryptedInputStream = new CipherInputStream(is, cipher);
return decryptedInputStream;
}
where eis is your encrypted input stream

Android: decrypt RSA text using a Public key stored in a file

I've been several days trying to do it without success.
There are plenty of similar questions here in StackOverflow and even two of them are exactly the same as mine but unanswered and unresolved:
1) Convert PHP RSA PublicKey into Android PublicKey
2) Android: how to decrypt an openssl encrypted file with RSA key?
My scenario:
I have some text encrypted using RSA (not encrypted by me). I have a "public.key" file in my res/raw folder with the public key needed to decrypt it (the public key related to the private key used to encrypt the message), with a format like the following example:
I see a lot of examples of how to decrypt a RSA text, like the following one:
public static byte[] decryptRSA( PublicKey key, byte[] text) throws Exception
{
byte[] dectyptedText = null;
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
return dectyptedText;
}
But my question is, how to get the proper PublicKey instance from the file? No examples of this.
If I simply try:
InputStream is = getResources().openRawResource(R.raw.public);
DataInputStream dis = new DataInputStream(is);
byte [] keyBytes = new byte [(int) is.available()];
dis.readFully(keyBytes);
dis.close();
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(spec);
I get an InvalidKeyException in the return sentence.
Would I need to decode Hex or Base64? Aren't the first and last lines of the public key file a problem (the ones with "----BEGIN PUBLIC KEY----" and so)?
Maybe we could get the answer of this properly for the first time in StackOverflow:-)
Finally solved!!! Drums, trumpets and a symphony of enchanting sounds!!!
public static byte[] decryptRSA(Context mContext, byte[] message) throws Exception {
// reads the public key stored in a file
InputStream is = mContext.getResources().openRawResource(R.raw.sm_public);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null)
lines.add(line);
// removes the first and last lines of the file (comments)
if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
lines.remove(0);
lines.remove(lines.size()-1);
}
// concats the remaining lines to a single String
StringBuilder sb = new StringBuilder();
for (String aLine: lines)
sb.append(aLine);
String keyString = sb.toString();
Log.d("log", "keyString:"+keyString);
// converts the String to a PublicKey instance
byte[] keyBytes = Base64.decodeBase64(keyString.getBytes("utf-8"));
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(spec);
// decrypts the message
byte[] dectyptedText = null;
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(Base64.decodeBase64(message));
return dectyptedText;
}
The solution was to Base64 decode not only the public key read from the file, but also the crypted message itself!
By the way, I read the public key from the file the way #Nikolay suggested (tnx again man).
Thank you all very much for your help. StackOverflow rocks!
You are missing a key point -- public and private keys are separate, and you cannot calculate one based on the other. That is kind of the point of public key encryption. Issues with using raw RSA aside, if you have something encrypted with the public key, you need to have the corresponding private key to decrypt it. And vice versa. So if you have public key file, you can only get a public key from it. That would be only useful if your data was encrypted with the corresponding private key.
As for the actual exception: remove the '---' lines at the start and end, the use Base64.decode() to get a byte array, and use this to create your X509EncodedKeySpec. One way to do it -- use something like a BufferedReader to read line by line, ignore the '---' lines and concat the rest into one big String.
Public keys can only encrypt data. Public keys cannot decrypt data. You can only decrypt data using the private key. The whole point is you can hand out the public key to any and everyone and they can send you encrypted messages that only the holder of the private key can see.
You really need to be very careful with using encryption technology. I fear you are simply going to distribute the private key to all of your devices which will weaken your security as everyone will have the same private key. So if I want to crack your security I just go to google play and download your app and pull the private key out of your app. Viola I can see everything.
So you have your answer why it won't work, but you need advice now about design which I can't give you with knowing why you are using encryption. What are you hiding?
Update:
Sounds like you are trying to perform encryption AND signature verification like how RSA works, but you are confused how that actually works. For that you need TWO sets of private/public keys. One set of keys for the client and one set of keys for the server.
The web server would send its public key to the client. The client could send an authenticated and encrypted message to the server by using the server's public key and then signing that message using the client's private key. And vice versa for the server. The server would use the client's public key to encrypt a message and sign it with his private key to send a message to the client. The client could then decrypt the message with the client's private key and verify the signature using the server's public key.
Now are you re-implementing SSL? Stop it. Use SSL.
Here is how SSL achieves secure channel. The client receives the PUBLIC key from the web server, and 1 or more names for symmetric encryption algorithms. It picks an algorithm they share in common, then generates a secret key to use for all messages going forward. It ENCRYPTS that secret key with the web server's public key and sends that along with the algorithm it selected. The web server DECRYPTS using the PRIVATE key to get the shared secret key. After that all encryption is symmetric encryption using the shared secret which is much faster than asymmetric encryption.
To generate a RSA public key from a PEM format like you provided (openssl gen. rsa key)
-----BEGIN PUBLIC KEY-----
SOMEDES3UNREADABLETEXT+PADDING==
-----END PUBLIC KEY
and use it to read some content signed with it?
-take a look at my answer in a similar question here:
https://stackoverflow.com/a/12101100/546054

Categories

Resources