Android - Encrypt Multiple Files Based on listFiles? - java

As a school project, I'm trying to achieve the following:
-List all files (pictures) in a folder.
Go through every picture one by one and password encrypt them using AES.
This is meant as an application to safely encrypt pictures, making only You able to decrypt and view them - provided you have the right password.
So far I am able to get all file names in the folder/directory, and encrypt only one specified file. The problem is, that I don't know how to go through the list, and encrypt all the files to the end.
Here is the code I am currently using:
package com.example.secretpictures;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
public class EncryptService extends Service {
private static final String TAG = EncryptService.class.getSimpleName();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d(TAG, "OnCreate");
}
#SuppressLint("SdCardPath")
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.d(TAG, "OnStart");
File file[] = Environment.getExternalStorageDirectory().listFiles();
recursiveFileFind(file);
try {
FileInputStream fis = new FileInputStream("/mnt/sdcard/secretpictures/yolo.png");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/secretpictures/yolo2.enc");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d(TAG, "OnDestroy");
}
public void recursiveFileFind(File[] file1){
int i = 0;
String filePath="";
if(file1!=null){
while(i!=file1.length){
filePath = file1[i].getAbsolutePath();
if(file1[i].isDirectory()){
File file[] = file1[i].listFiles();
recursiveFileFind(file);
}
i++;
Log.d(i+"", filePath);
}
}
}
}
As you see, it's very ugly coded, but get's the job done for now.
This service is called when the mainactivity is created.
This line specifies the file to be encrypted: FileInputStream fis = new FileInputStream("/mnt/sdcard/secretpictures/yolo.png");
How would one approach getting the inputstream to go through File file[] = file1[i].listFiles(); to encrypt every and all of the files?

Once you have a File object as shown in your code that finds files you can obtain a FileInputStream for that file using the constructor FileInputStream(File).
Some notes on your crypto system. It isn't very secure. In no particular order
You use a UTF-8 bytes directly without a salt for you key material. Use a key stretching
algorithm like PBKDF2 and feed the password bytes to it with a salt. You can store the salt as plaintext with the encrypted image.
You're using the default cipher spec for AES. This expands to AES/ECB/PKCS5Padding. ECB is not a secure mode for your encrypting more than 1 block of plaintext (16 bytes for AES). ECB fails to hide patterns in the plaintext due to the fact that the same input plaintext results in the same output ciphertext. Images are particularly vulnerable to this due to repeating patterns. See this Wikipedia article for more info on ECB, it also gives an encrypted image as an example. Most other modes you can use (CBC, CTR, etc) required an IV, the IV should be randomly generated and you can store it in the clear with the encrypted image.

Related

how to encrypt/decrypt text in android studio on different activities

I tried developing an text encryption/decryption app in android studio. So here on the MainActivity.java i ran a sample code of encryption & decryption.
MainActivity.java
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class MainActivity extends AppCompatActivity {
Button btn,btn2;
static final String TAG = "SymmetricAlgorithmAES";
String secr="k";
String secr2="d";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//code to use my specified defined key
byte[] key = new byte[0];
try {
key = (secr+secr2).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
MessageDigest sha = null;
try {
sha = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
SecretKeySpec sks = new SecretKeySpec(key, "AES");
// Original text
String theTestText = "This is just a simple test";
TextView tvorig = (TextView)findViewById(R.id.tvorig);
tvorig.setText("\n[ORIGINAL]:\n" + theTestText + "\n");
// Encode the original data with AES
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, sks);
encodedBytes = c.doFinal(theTestText.getBytes());
} catch (Exception e) {
Log.e(TAG, "AES encryption error");
}
TextView tvencoded = (TextView)findViewById(R.id.tvencoded);
tvencoded.setText("" +
Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
// Decode the encoded data with AES
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, sks);
decodedBytes = c.doFinal(encodedBytes);
} catch (Exception e) {
Log.e(TAG, "AES decryption error");
}
TextView tvdecoded = (TextView)findViewById(R.id.tvdecoded);
tvdecoded.setText("[DECODED]:\n" + new String(decodedBytes) + "\n");
}
The above code works properly with correct output. But when i try to modify the code and try to write encryption and decryption in different activities, but the decryption part does not work properly.
Here is the code for encryption part which works properly without any error.
Encryption.java
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Encryption extends AppCompatActivity {
static final String TAG = "SymmetricAlgorithmAES";
String secr="k";
String secr2="d";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.encryption);
enc_text_edt=(EditText)findViewById(R.id.enc_text_edt);
enc_text_btn=(Button)findViewById(R.id.enc_text_btn);
enctv=(TextView)findViewById(R.id.enctv);
//code to use my specified defined key
byte[] key = new byte[0];
try {
key = (secr+secr2).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
MessageDigest sha = null;
try {
sha = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
SecretKeySpec sks = new SecretKeySpec(key, "AES");
final SecretKeySpec finalSks = sks;
enc_text_btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
// Encode the original data with AES
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, finalSks);
encodedBytes = c.doFinal(enc_text_edt.getText().toString().getBytes());
} catch (Exception e) {
Log.e(TAG, "AES encryption error");
}
enctv.setText("[ENCRYPTED]:\n" +
Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
enc_text_edt.setText("");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
code of Decryption
Decryption.java
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Decryption extends AppCompatActivity {
Button dec_text_btn;
TextView dec_edtext_view, dectv;
static final String TAG = "SymmetricAlgorithmAES";
String secr = "k";
String secr2 = "d";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.decryption);
dec_text_btn = (Button) findViewById(R.id.dec_text_btn);
dec_edtext_view = (EditText) findViewById(R.id.dec_edtext_view);
dectv = (TextView) findViewById(R.id.dectv);
//code to use my specified defined key
byte[] key = new byte[0];
try {
key = (secr + secr2).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
MessageDigest sha = null;
try {
sha = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
SecretKeySpec sks = new SecretKeySpec(key, "AES");
final SecretKeySpec finalSks = sks;
dec_text_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
// Decode the encoded data with AES
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, finalSks);
decodedBytes= c.doFinal(dec_edtext_view.getText().toString().getBytes());
} catch (Exception e) {
Log.e(TAG, "AES encryption error");
}
dectv.setText("[DECRYPTED]:\n" + new String(decodedBytes) + "\n");
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "creptography exception see log cat....", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Please help me with the error. While executing Decryption part it directly shows exception "creptography exception see log cat".
After reading your code I think I have found the problem, you encode to Base64 but never decode. In the Encryption you do the following
enctv.setText("[ENCRYPTED]:\n" +
Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
and I can guess the user copies it to the decryption field but after they click the button you do
decodedBytes= c.doFinal(dec_edtext_view.getText().toString().getBytes());
instead of decoding from Base64.
I would also like to add a few notes:
You're security is not safe, you barely achieved any layer of security when the keys are in plane site like this.
Note 1:
Keys should be generated randomly with a SecureRandom.
You can easily do it by doing the following:
byte[] key = new byte[16];
new SecureRandom().nextBytes(key);
Note 2:
Use an initialization vector aka IV this is useful in case the user has typed the same message. For example consider the following scenario you encrypt "Hello World" and it comes out as "ABCDEFGHIJK". Now you send it again and it is again "ABCDEFGHIJK".
With an IV it will be different everytime as long as you generate a new IV per message, you should append this IV to the message so later in decryption you can extract it.
Note 3:
When declaring a Cipher use more than AES.
There is a great article about how to increase your security and knowledge: article link
Note 4:
If an exception occurs don't continue on like nothing happend, you should handle it correctly and not continue on code that depends on what caused the exception.
Note 5:
Learn Java more in depth instead of jumping to cryptography, you're fields should be private and some final don't declare null if you might be planning to use it later, if you do check if its null. Don't declare "UTF-8" in get bytes, have a constant declaring a Charset such as "UTF-8" this is easily done with Charset.forName("UTF-8")
I agree with everything OughtToPrevail said.
Also, you should probably get all of that out of your activity and into a helper class. That way it will be reusable, and you can test the in and out of it (without copying and pasting) with something that would look like this:
public void myEncryptionTest(){
String message = "This is the message to encrypt and decrypt.";
String pass = "pass";
String encryption = Crypto.myEncrypt(message.getBytes(), pass);
byte[] decryption = Crypto.myDecrypt(encryption, pass);
String decrypted = new String(decryption);
Log.d("****DECRYPTION: ", decrypted);
}
Where the helper class is called "Crypto" and the two static functions you're testing are "myEncrypt" and "myDecrypt."

How to fix my Encryption/Decryption code to go into a text file

Every time I run the code it says that the deciphered text file can't be found. It works without the code I can't modify (because my teacher wrote that we can't) but with it, it refuses to work. My teacher won't help me and no one else in my class knows how to code with the cipher class. I have used the PrintWriter class, and pretty much everything else. So I don't know what to do. Someone please help me figure out how to make it work.
package Crypto;
import java.util.Scanner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.FileWriter;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class Crypto {
public static void main(String[] args) throws IOException {
try {
String key = "B1LLYB0B";
FileInputStream One = new FileInputStream("CryptoPlaintext.txt");
FileOutputStream Two = new FileOutputStream("CryptoCiphertext.txt");
encrypt(key, One, Two);
Two.flush();
Two.close();
FileInputStream One2 = new FileInputStream("CryptoCiphertext.txt");
FileOutputStream Two2 = new FileOutputStream("CryptoDeciphered.txt");
Two2.write(key.getBytes());
Two2.close();
decrypt(key, One2, Two2);
} catch (Throwable e) {
e.printStackTrace();
}
}
public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable {
encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
}
public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable {
encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
}
public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES");
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
doCopy(cis, os);
} else if (mode == Cipher.DECRYPT_MODE) {
cipher.init(Cipher.DECRYPT_MODE, desKey);
CipherOutputStream cos = new CipherOutputStream(os, cipher);
doCopy(is, cos);
}
}
public static void doCopy(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[64];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
os.write(bytes, 0, numBytes);
}
os.flush();
os.close();
is.close();
// =============================== DO NOT MODIFY ANY CODE BELOW HERE ===============================
// Compare the files
System.out.println(compareFiles() ? "The files are identical!" : "The files are NOT identical.");
}
/**
* Compares the Plaintext file with the Deciphered file.
*
* #return true if files match, false if they do not
*/
public static boolean compareFiles() throws IOException
{
Scanner pt = new Scanner(new File("CryptoPlaintext.txt")); // Open the plaintext file
Scanner dc = new Scanner(new File("CryptoDeciphered.txt")); // Open the deciphered file
// Read through the files and compare them record by record.
// If any of the records do not match, the files are not identical.
while(pt.hasNextLine() && dc.hasNextLine())
if(!pt.nextLine().equals(dc.nextLine())) return false;
// If we have any records left over, then the files are not identical.
if(pt.hasNextLine() || dc.hasNextLine()) return false;
// The files are identical.
return true;
}
}
Why the error occurs:
You invoke the method compareFiles in your copy method, which is called to copy the encrypted content of the plaintext file to the cipher text file. When this call occurs the file containing the decrypted cipher text doesn't exist but is required by the compareFiles method resulting in your exception.
How to improve your code:
you don't need the statement Two2.write(key.getBytes())
use the try-with-resource statement to automatically flush and close your streams
the standard library provides methods to copy data from a path to a stream and vice versa. Have a look at Files.copy(...) or Guava's ByteStreams.copy(...)
change your methods' throws clause, throws Throwable is just bad design to get rid of proper exception handling, if you are struggling with InvalidKeyException, NoSuchAlgorithmException, etc, catch these when you create your cipher and rethrow e.g. IllegalArgumentException or a custom exception
Here is an example how to implement it:
public class Crypto
{
public static void main(String[] args)
{
byte[] key = "B1LLYB0B".getBytes(StandardCharsets.UTF_8);
Path plaintext = Paths.get("CryptoPlaintext.txt");
Path ciphertext = plaintext.resolveSibling("CryptoCiphertext.txt");
Path decrypted = ciphertext.resolveSibling("CryptoDeciphered.txt");
try
{
// Encrypt plaintext.
try (OutputStream os = encrypt(key, Files.newOutputStream(ciphertext)))
{
Files.copy(plaintext, os);
}
// Decrypt ciphertext.
try (InputStream is = decrypt(key, Files.newInputStream(ciphertext)))
{
Files.copy(is, decrypted);
}
// TODO Compare plaintext and decrypted ciphertext.
}
catch (IOException e)
{
e.printStackTrace(); // TODO Handle exception properly.
}
}
private static OutputStream encrypt(byte[] key, OutputStream os)
{
return new CipherOutputStream(os, getCipherInstance(key, Cipher.ENCRYPT_MODE));
}
private static InputStream decrypt(byte[] key, InputStream is)
{
return new CipherInputStream(is, getCipherInstance(key, Cipher.DECRYPT_MODE));
}
private static Cipher getCipherInstance(byte[] key, int mode)
{
// TODO Implement and return the desired cipher.
}
}
By the way: Your teacher doesn't close his scanners in compareFiles() resulting in a resource leak.

Exception while trying to verify a digital signature

I run a java program to verify digital signature
package com.cryptography;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
public class VerifyDkimSignature {
public static void main(String[] args) {
FileInputStream fis;
try {
//Read encoded public key bytes
fis = new FileInputStream
("/home/src/com/cryptography/DkimPublicKey");
byte[] encKey = new byte[fis.available()];
fis.read(encKey);
fis.close();
//Generate public key
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
//Read signature bytes from file
BufferedInputStream bis = new BufferedInputStream
(new FileInputStream
("/home/src/com/cryptography/Signature"));
byte[] signatureBytes = new byte[bis.available()];
bis.read(signatureBytes);
//Initialise signature instance
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(pubKey);
//Supply signature object with the data for verification
bis = new BufferedInputStream
(new FileInputStream
("/home/src/com/cryptography/SampleFile.txt"));
byte[] origFile = new byte[1024];
int len = 0;
while(bis.available() != 0) {
len = bis.read(origFile);
sig.update(origFile, 0, len);
}
boolean isVerifies = sig.verify(signatureBytes);
System.out.println("Signature verifies::"+isVerifies);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SignatureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When I execute it, I get the following exception
java.security.SignatureException: Signature encoding error
at sun.security.rsa.RSASignature.engineVerify(Unknown Source)
at java.security.Signature$Delegate.engineVerify(Unknown Source)
at java.security.Signature.verify(Unknown Source)
at com.cryptography.VerifyDkimSignature.main(VerifyDkimSignature.java:54)
Caused by: java.io.IOException: ObjectIdentifier mismatch: 1.3.14.3.2.26
at sun.security.rsa.RSASignature.decodeSignature(Unknown Source)
... 4 more
Can someone please explain the reason for the error?
It turns out that "1.3.14.3.2.26" (from the IOException) is the OID for a SHA-1 algorithm. So the mistake which I have done here is using different algorithms for verification and signing i.e I have used SHA1withRSA for signing and SHA256With RSA for verification. This got resolved once I changed the algorithm at the verification end to SHA1WithRSA

decryption issue in java

I am playing around with saving/loading a text file in Android, works fine. Next step is to encrypt and decrypt with AES.
I can call the encrypt() method within the writetofile method,a dn that works fine. If i call the readfromfile method, I can see the ciphertext is retrieved, great.
But decryption isnt working for me - I have called simplecrypo in a few places - on stringBuffer.toString(), and within the StringBuffer's append() method - but both crash the application.
So does anybody know where I am supposed to decrypt the string within the file?
package com.example.filesdemo;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText etInput;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etInput = (EditText) findViewById(R.id.etInput);
}
public void writeToFile(View v) throws Exception {
try {
String inputStr = etInput.getText().toString();
//encrypt the string - works!
String encrypted = SimpleCrypto.encrypt("testkey", inputStr);
FileOutputStream fos = openFileOutput("myfile.txt", MODE_PRIVATE);
fos.write(encrypted.getBytes());
fos.flush();
fos.close();
Toast.makeText(this, "File saved!", Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void readFromFile(View v) throws Exception{
try {
FileInputStream fis = openFileInput("myfile.txt");
StringBuffer stringBuffer = new StringBuffer();
BufferedReader bReader = new BufferedReader(new InputStreamReader(
fis));
String strLine = null;
while ((strLine = bReader.readLine()) != null) {
stringBuffer.append(strLine + "\n");
}
bReader.close();
fis.close();
Toast.makeText(this, "File content: \n" +stringBuffer.toString(),
Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the encryption class is publically available here - decrypt class, but i dont think thats the issue.
Thanks!
From the look of things, you are writing the encrypted bytes to the file, and then trying to read them back as text into a Scanner. That won't work, as you have found.
If you want your file to be text, then you need to convert the bytes to Base64 and write as text. On reading the Base64 text, convert back to bytes and decypher. Java 8 has the Base64 class, I an not sure about Android.
If you want the file as raw bytes, then you need to read it as bytes, not as text. Once read as bytes it can be decyphered directly.

Java - length of a buffer to write a file

This is a question concerning setting the size of a byte array for a buffer to write() a local file from a URL stream:
byte[] buffer = new byte[26];
26 seems to be the magic number. If I put anything above 26 (say 1024), it still only writes the first 26 characters into the file. Why? Please note that I'm not trying to write the entire stream (using the while loop) just trying to figure out why the biggest chunk is only 26 characters long.
Here's the full code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class ReadNetworkFile {
public static void main(String[] args){
File f2 = new File("target3.txt");
try {
OutputStream out = new FileOutputStream(f2);
URL url = new URL("http://services.explorecalifornia.org/rss/tours.php");
InputStream stream = url.openStream();
byte[] buffer = new byte[1024];
int len=stream.read(buffer);
out.write(buffer,0,len);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You're missing the magic ingredient: the while-loop.
You need to read from the web and write to the file while len > 0. Then you've finished.

Categories

Resources