I am sign and encrypt a text file of 12 GB using (bcpg-jdk16-145.jar , bcprov-jdk16-145.jar) jar files. File will be encrypted and signed approximately 18 minutes in Windows Vista , jdk 1.6. But when I try to encrypt it on LINUX/UNIX system process will become very slow I takes 1 to 1:30 hours. Kindly suggest.
Code for signing file is as below :
private static void signFile(String fileName, InputStream keyIn,
OutputStream out, char[] pass, boolean armor, int bufferSize)
throws IOException, NoSuchAlgorithmException,
NoSuchProviderException, PGPException, SignatureException {
if (armor) {
out = new ArmoredOutputStream(out);
}
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(pass, "BC");
PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec
.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
Iterator it = pgpSec.getPublicKey().getUserIDs();
if (it.hasNext()) {
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, (String) it.next());
sGen.setHashedSubpackets(spGen.generate());
}
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
PGPCompressedData.ZLIB);
BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
sGen.generateOnePassVersion(false).encode(bOut);
File file = new File(fileName);
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, file);
FileInputStream fIn = new FileInputStream(file);
byte[] byteArray = new byte[bufferSize];
while (fIn.read(byteArray) >= 0) {
lOut.write(byteArray);
sGen.update(byteArray);
}
lGen.close();
sGen.generate().encode(bOut);
cGen.close();
out.close();
}
This is an educated guess, maybe you're having a problem with /dev/random?
PGP is going to use a secure hash, which in Java will probably rely on SecureRandom. The default source for SecureRandom in Linux (but not Windows) is /dev/random.
The problem is that SecureRandom will block waiting for /dev/random to gather more entropy if it currently can't satisfy the number of bits requested.
Try installing a utility called "haveged" (apt-get install or whatever). It will gather more entropy for your linux system and prevent this behavior.
Related
In my java program I would like to read a .txt file in and encode it afterwards. I know how to read a File in and tried to learn how to encode an array. The problem I have is that I don't know how to combine it, it doesn't work the way I tried it.
Here's the part I can read in my text file with:
public class ReadFile {
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fr);
String zeile = "";
do
{
zeile = br.readLine();
System.out.println(zeile);
}
while (zeile != null);
br.close();
}
}
In this part I can encrypt and decrypt bytes:
public class Crypt {
public static void main(String[] args) {
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desalgCipher;
desalgCipher = Cipher.getInstance("DES");
byte[] text = "test".getBytes("UTF8");
desalgCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
byte[] textEncrypted = desalgCipher.doFinal(text);
String s = new String(textEncrypted);
System.out.println(s);
desalgCipher.init(Cipher.DECRYPT_MODE, myDesKey);
byte[] textDecrypted = desalgCipher.doFinal(textEncrypted);
s = new String(textDecrypted);
System.out.println(s);
}
catch(Exception e)
{
System.out.println("Error");
}
}
}
I thought to read the text file in and put it in a string to encode it, but I think it is way too complex. Is there another way to connect them, or is another way for encoding required?
I strongly advise you to use Streams ( see https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html & https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html) rather than directly using a FileReader.
Encryption happens at a lower level (on bytes) than what you're trying to do.
Java ciphers offer the convenient CipherInputStream (and CipherOutputStream ) to encrypt byte streams on the fly. It's much cheaper and more scalable than trying to dump a whole file in a single byte[] (moreso because you're decoding and re-encoding the file content).
If you want an example of use, please look at the following snippet :
public static void encrypt(Path inputFile, OutputStream output) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
// init cipher
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desalgCipher;
desalgCipher = Cipher.getInstance("DES");
desalgCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
try(InputStream is = Files.newInputStream(inputFile); // get an IS on your file
CipherInputStream cipherIS = new CipherInputStream(is, desalgCipher)){ // wraps input Stream with cipher
copyStreams(cipherIS, output); // copyStream is let to the implementer's choice.
}
}
And I'll let you figure out how to decrypt.
EDIT :
A common way to communicate encrypted bytes without fear for encoding issues is to encode the raw bytes with base 64.
You can wrap the outputStream with Base64.getEncoder().wrap(os)
FileReader/FileWriter are the wrong (old utility) classes, as they use the current platform encoding, and a file encrypted on one computer (Greek Windows) would not be decryptable on another computer (Linux server).
Text in java, String, is in Unicode. One cannot (should not) throw arbitrary bytes into a String.
So the following cannot be done
new String(textEncrypted); // Uses the default platform encoding
new String(textEncrypted, "UTF-8"); // Probably the bytes are not valid UTF-8
So do:
Path path = Paths.get("text.txt");
byte[] content = Files.readAllBytes(path);
content = encrypt(content);
Files.write(path, content);
I'm currently writing an encrypted messaging service in java, and I'm using the bouncycastle PGP library. I have written a test program that generates a key pair, and encrypts/decrypts a message. This was working for a while, but it recently stopped in the decrypt stage, giving me an InvalidKeyException.
I've done some research and downloaded the JCE .jar files and imported them into my project (through Eclipse project -> properties -> add external JARs). I saw that for windows users, they should be put into a specific folder in the java library, but i couldn't find a similar one on my Mac. I tried looking through the usr/library folder but couldn't find anything of use.
Has anyone solved this issue on Mac?
EDIT: here's some code from my main test function
// decrypt
byte[] decrypted = PGPEncryptDecrypt.decrypt(encFromFile, secKey, pass.toCharArray());
Here's my decrypt method( this was not written by me, but I made a PGPEncryptDecrypt class to hold related static methods, and it worked for me)
public static byte[] decrypt(byte[] encrypted, InputStream keyIn, char[] password)
throws IOException, PGPException, NoSuchProviderException {
InputStream in = new ByteArrayInputStream(encrypted);
in = PGPUtil.getDecoderStream(in);
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc = null;
Object o = pgpF.nextObject();
//
// the first object might be a PGP marker packet.
//
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
//
// find the secret key
//
Iterator it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn));
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
sKey = findSecretKey(pgpSec, pbe.getKeyID(), password);
}
if (sKey == null) {
throw new IllegalArgumentException(
"secret key for message not found.");
}
InputStream clear = pbe.getDataStream(sKey, "BC");
PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject();
pgpFact = new PGPObjectFactory(cData.getDataStream());
PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
InputStream unc = ld.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
int ch;
while ((ch = unc.read()) >= 0) {
out.write(ch);
}
byte[] returnBytes = out.toByteArray();
out.close();
return returnBytes;
}
The error points to the findSecretKey (in PGPEncryptDecrypt class) method, which is as follows
public static PGPPrivateKey findSecretKey(
PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
throws PGPException, NoSuchProviderException {
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
if (pgpSecKey == null) {
return null;
}
return pgpSecKey.extractPrivateKey(pass, "BC");
}
These functions all worked perfectly when i first implemented them, but they stopped working.
For anyone else looking, i found the answer to this after digging around a little.
what i did was open terminal, enter root library (as sudo), found the appropriate java library, and did a manual copy from my downloads folder into the appropriate java security folder
path was Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/jre/lib/security
then in there i did two cp filename commands to copy the appropriate file
I discovered that Java 7 introduced a zip FileSystem. Currently I have a encrypted zip files, that I'm decrypting with the following code
InputStream in = new FileInputStream(inFile);
Crypto algo = new Crypto();
algo.initV1();
in = new CipherInputStream(in, algo.getCiphertoDec(in, pass));
ZipInputStream zipInput = new ZipInputStream(in);
ZipEntry ze = zipInput.getNextEntry();
....
and the method getCiphertoDec is like this
public Cipher getCiphertoDec (InputStream in, String password) throws Exception {
byte[] salt = new byte[SALT_SIZE_BYTE];
if (in.read(salt) < SALT_SIZE_BYTE) {
throw new IllegalArgumentException("Invalid file length (needs a full block for salt)");
};
key = CoreCryptoV1.PBKDF2.pbkdf2(password, salt, 1000);
ivBytes = new byte[IV_LENGTH_BYTE];
if (in.read(ivBytes) < IV_LENGTH_BYTE) {
throw new IllegalArgumentException("Invalid file length (needs a full block for iv)");
};
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivBytes));
return cipher;
}
I wonder if there is any way to treat encrypted zip file as a file system.
I appreciate any advice.
I would like a solution that is compatible with android.
let me start by saying I'm extremely new to all of this. What I am trying to do is to use gpg from within Java in order to decrypt an encrypted file.
What I've done successfully:
Had a colleague encrypt a file using my public key and his private key and successfully decrypted it.
Went the other way
Had another colleague try to decrypt a file that wasn't for him: fail (as expected)
My key was generated like this...
(gpg --version tells me I'm using 1.4.5 and I'm using Bouncy Castle 1.47)
gpg --gen-ley
Select option "DSA and Elgamal (default)"
Fill in the other fields and generate a key.
The file was encrypted using my public key and another's secret key. I want to decrypt it. I've written the following Java code to accomplish this. I'm using several deprecated methods, but I can't figure out how to properly implement the factory methods required to use the non-deprecated versions, so if anyone has an idea on implementations of those that I should be using that would be a nice bonus.
Security.addProvider(new BouncyCastleProvider());
PGPSecretKeyRingCollection secretKeyRing = new PGPSecretKeyRingCollection(new FileInputStream(new File("test-files/secring.gpg")));
PGPSecretKeyRing pgpSecretKeyRing = (PGPSecretKeyRing) secretKeyRing.getKeyRings().next();
PGPSecretKey secretKey = pgpSecretKeyRing.getSecretKey();
PGPPrivateKey privateKey = secretKey.extractPrivateKey("mypassword".toCharArray(), "BC");
System.out.println(privateKey.getKey().getAlgorithm());
System.out.println(privateKey.getKey().getFormat());
PGPObjectFactory pgpF = new PGPObjectFactory(
new FileInputStream(new File("test-files/test-file.txt.gpg")));
Object pgpObj = pgpF.nextObject();
PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList) pgpObj;
Iterator objectsIterator = encryptedDataList.getEncryptedDataObjects();
PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) objectsIterator.next();
InputStream inputStream = publicKeyEncryptedData.getDataStream(privateKey, "BC");
So when I run this code I learn that my algorithm and format are as follows for my secret key:
Algorithm: DSA
Format: PKCS#8
And then it breaks on the last line:
Exception in thread "main" org.bouncycastle.openpgp.PGPException: error setting asymmetric cipher
at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder.decryptSessionData(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder.access$000(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder$2.recoverSessionData(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at TestBouncyCastle.main(TestBouncyCastle.java:74)
Caused by: java.security.InvalidKeyException: unknown key type passed to ElGamal
at org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(Unknown Source)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
... 8 more
I'm open to a lot of suggestions here, from "don't use gpg, use x instead" to "don't use bouncy castle, use x instead" to anything in between. Thanks!
If anyone is interested to know how to encrypt and decrypt gpg files using bouncy castle openPGP library, check the below java code:
The below are the 4 methods you going to need:
The below method will read and import your secret key from .asc file:
public static PGPSecretKey readSecretKeyFromCol(InputStream in, long keyId) throws IOException, PGPException {
in = PGPUtil.getDecoderStream(in);
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in, new BcKeyFingerprintCalculator());
PGPSecretKey key = pgpSec.getSecretKey(keyId);
if (key == null) {
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
return key;
}
The below method will read and import your public key from .asc file:
#SuppressWarnings("rawtypes")
public static PGPPublicKey readPublicKeyFromCol(InputStream in) throws IOException, PGPException {
in = PGPUtil.getDecoderStream(in);
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in, new BcKeyFingerprintCalculator());
PGPPublicKey key = null;
Iterator rIt = pgpPub.getKeyRings();
while (key == null && rIt.hasNext()) {
PGPPublicKeyRing kRing = (PGPPublicKeyRing) rIt.next();
Iterator kIt = kRing.getPublicKeys();
while (key == null && kIt.hasNext()) {
PGPPublicKey k = (PGPPublicKey) kIt.next();
if (k.isEncryptionKey()) {
key = k;
}
}
}
if (key == null) {
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
return key;
}
The below 2 methods to decrypt and encrypt gpg files:
public void decryptFile(InputStream in, InputStream secKeyIn, InputStream pubKeyIn, char[] pass) throws IOException, PGPException, InvalidCipherTextException {
Security.addProvider(new BouncyCastleProvider());
PGPPublicKey pubKey = readPublicKeyFromCol(pubKeyIn);
PGPSecretKey secKey = readSecretKeyFromCol(secKeyIn, pubKey.getKeyID());
in = PGPUtil.getDecoderStream(in);
JcaPGPObjectFactory pgpFact;
PGPObjectFactory pgpF = new PGPObjectFactory(in, new BcKeyFingerprintCalculator());
Object o = pgpF.nextObject();
PGPEncryptedDataList encList;
if (o instanceof PGPEncryptedDataList) {
encList = (PGPEncryptedDataList) o;
} else {
encList = (PGPEncryptedDataList) pgpF.nextObject();
}
Iterator<PGPPublicKeyEncryptedData> itt = encList.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData encP = null;
while (sKey == null && itt.hasNext()) {
encP = itt.next();
secKey = readSecretKeyFromCol(new FileInputStream("PrivateKey.asc"), encP.getKeyID());
sKey = secKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
}
if (sKey == null) {
throw new IllegalArgumentException("Secret key for message not found.");
}
InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
pgpFact = new JcaPGPObjectFactory(clear);
PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject();
pgpFact = new JcaPGPObjectFactory(c1.getDataStream());
PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
InputStream inLd = ld.getDataStream();
int ch;
while ((ch = inLd.read()) >= 0) {
bOut.write(ch);
}
//System.out.println(bOut.toString());
bOut.writeTo(new FileOutputStream(ld.getFileName()));
//return bOut;
}
public static void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey) throws IOException, NoSuchProviderException, PGPException {
Security.addProvider(new BouncyCastleProvider());
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));
comData.close();
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom()));
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey));
byte[] bytes = bOut.toByteArray();
OutputStream cOut = cPk.open(out, bytes.length);
cOut.write(bytes);
cOut.close();
out.close();
}
Now here is how to invoke/run the above:
try {
decryptFile(new FileInputStream("encryptedFile.gpg"), new FileInputStream("PrivateKey.asc"), new FileInputStream("PublicKey.asc"), "yourKeyPassword".toCharArray());
PGPPublicKey pubKey = readPublicKeyFromCol(new FileInputStream("PublicKey.asc"));
encryptFile(new FileOutputStream("encryptedFileOutput.gpg"), "fileToEncrypt.txt", pubKey);
} catch (PGPException e) {
fail("exception: " + e.getMessage(), e.getUnderlyingException());
}
To any one looking for an alternative solution, see https://stackoverflow.com/a/42176529/7550201
final InputStream plaintextStream = BouncyGPG
.decryptAndVerifyStream()
.withConfig(keyringConfig)
.andRequireSignatureFromAllKeys("sender#example.com")
.fromEncryptedInputStream(cipherTextStream)
Long story short: Bouncycastle is programming is often a lot of cargo cult programming and I wrote a library to change that.
I've decided to go with a much different approach, which is to forego the use of bouncy castle altogether and simply use a runtime process instead. For me this solution is working and completely removes the complexity surrounding bouncy castle:
String[] gpgCommands = new String[] {
"gpg",
"--passphrase",
"password",
"--decrypt",
"test-files/accounts.txt.gpg"
};
Process gpgProcess = Runtime.getRuntime().exec(gpgCommands);
BufferedReader gpgOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream()));
BufferedReader gpgError = new BufferedReader(new InputStreamReader(gpgProcess.getErrorStream()));
After doing that you need to remember to drain your input stream as your process is execing or your program will probably hang depending on how much you're outputing. See my answer in this thread (and also that of Cameron Skinner and Matthew Wilson who got me on the proper path) for a bit more context: Calling GnuPG in Java via a Runtime Process to encrypt and decrypt files - Decrypt always hangs
The first Google result is this. It looks like you are trying to decrypt ElGamal data, but you are not passing in an ElGamal key.
There are two easy possibilities:
Your keyring collection has multiple keyrings.
Your keyring has subkeys.
You've picked DSA with ElGamal encryption, so I suspect at least the latter: Subkeys are signed by the master key; ElGamal is not a signing algorithm (I don't know if DSA and ElGamal can use the same key, but it's generally seen as a good idea to use different keys for different purposes).
I think you want something like this (also, secretKeyRing should probably be renamed to secretKeyRingCollection):
PGPSecretKey secretKey = secretKeyRing.getSecretKey(publicKeyEncryptedData.getKeyID());
The error message is difficult because it's not completely accurate. Besides the illegal key size or default parameters the exception doesn't says it could be failing because of crypto permission check fails. That means you haven't setup the JCE permissions properly. You'll need to install the JCE Unlimited Strength Policy.
You can see the debug messages by setting the system property on the jvm
java -Djava.security.debug=access ....
I have a program that has to encrypt an audio file and then decrypt it if needed. I tested my program on some other types of files, like .bin or .txt. The problem I get is that the decrypted file has some weird characters before the actual content, like the source file contains "010101" and after encryption-decryption it has "’w0w 010101".
My encryption method code goes here:
public void cipherTheAudioFile(String fileDir, String fileToCipher) throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException {
File audioSourceFile = new File(fileDir + "\\" + fileToCipher);
ObjectOutputStream oos = new ObjectOutputStream(
new CipherOutputStream(new FileOutputStream(
new java.io.File("").getAbsolutePath().toString() + "/encrypted/" + fileToCipher + ".sky"), cipher));
byte[] audioFileInBytes = FileUtils.readFileToByteArray(audioSourceFile);
oos.write(audioFileInBytes);
fos = new FileOutputStream(KEY_FILE);
SecretKeyFactory skf = SecretKeyFactory.getInstance(ENCRYPTION_ALGORITHM);
DESKeySpec keyspec = (DESKeySpec) skf.getKeySpec(key, DESKeySpec.class);
fos.write(keyspec.getKey());
fos.close();
oos.close();
}
My decryption method code goes here:
public void decryptTheAudioFile(String fileDir, String fileToDecipher) throws NoSuchAlgorithmException, NoSuchPaddingException, FileNotFoundException, IOException, ClassNotFoundException, InvalidKeySpecException, InvalidKeyException {
fis = new FileInputStream(keyFile);
byte[] keyspecbytes = new byte[fis.available()];
File fileToWriteIn = createFileToWriteIn(fileDir, fileToDecipher);
fis.read(keyspecbytes);
SecretKeyFactory skf = SecretKeyFactory.getInstance(encryptionAlgorithm);
DESKeySpec keyspec = new DESKeySpec(keyspecbytes);
SecretKey key = skf.generateSecret(keyspec);
Cipher cipher = Cipher.getInstance(encryptionAlgorithm);
cipher.init(Cipher.DECRYPT_MODE, key);
ObjectInputStream ois = new ObjectInputStream(
new CipherInputStream(
new FileInputStream(new java.io.File("").getAbsolutePath().toString() + "/encrypted/" + fileToDecipher + ".sky"), cipher));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileToWriteIn));
byte[] audioFileInBytes = new byte[1024];
int numRead = 0;
while ((numRead = ois.read(audioFileInBytes)) >= 0) {
oos.write(audioFileInBytes, 0, numRead);
}
oos.close();
fis.close();
ois.close();
}
P.S. It could be something with the encoding, but I am not really sure.
EDITED
Ok, I have changed to the FileWriters, but still no change. Here goes the code:
OutputStream os = new FileOutputStream(new java.io.File("").getAbsolutePath().toString() + "/encrypted/" + fileToCipher + ".sky");
CipherInputStream cis = new CipherInputStream(new FileInputStream(audioSourceFile), cipher);
byte[] audioFileInBytes = new byte[1024];
int numRead = 0;
while ((numRead = cis.read(audioFileInBytes)) >= 0) {
os.write(audioFileInBytes, 0, numRead);
}
Likewise goes the decryptor.
The problem is in the way that the decryptTheAudioFile method writes the file. Specifically, the problem is that it is using an ObjectOutputStream. That is adding an object serialization header. But it doesn't belong there at all.
The solution is to get rid of this from decryptTheAudioFile:
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(fileToWriteIn));
and replace it with this:
OutputStream os = new FileOutputStream(fileToWriteIn);
and change the rest of the code to write to os. Your code needs to mirror how you are reading the file in cipherTheAudioFile.
It would be a good idea to get rid of the other ObjectStream instances too and simply read and write to plain Streams. The other ObjectStreams are harmless (mostly), but they don't actually achieve anything.
Drop all the ObjectOutputStreams and ObjectInputStreams. You are writing a byte array so they are unnecessary. The extra bytes you see are probably telling you the type and size of the byte[].