Java : can't decrypt what I encrypt - java

sorry if my question is silly but I'm learning java, I'm working on a project where encrypt and decrypt is needed I'm done with the code and the button for encrypting is fully functional but when I try to decrypt (different button) there is an error all the time.
encrypt code
path = chooser.getSelectedFile();
String x = path.toString();
try {
Scanner scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desCipher;
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes("UTF8");
desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
byte[] textEncrypted = desCipher.doFinal(text);
String s = new String(textEncrypted);
try {
File statText = new File(x);
FileOutputStream is = new FileOutputStream(statText);
OutputStreamWriter osw = new OutputStreamWriter(is);
Writer w = new BufferedWriter(osw);
w.write(s);
w.close();
}
catch (IOException e3) {
JOptionPane.showMessageDialog(null, "something is wrong with the txt file");
}
}catch(Exception e1)
{
System.out.println("En");
}
and here is the decrypt part :
path = chooser.getSelectedFile();
String x = path.toString();
try {
Scanner scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desCipher;
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes("UTF8");
byte[] textEncrypted = desCipher.doFinal(text);
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
byte[] textDecrypted = desCipher.doFinal(textEncrypted);
String s = new String(textDecrypted);
System.out.println(s);
}catch(Exception e1)
{
System.out.println("De"); /* here we go this is my error*/
}
the error at the second code "catch(Exception e1)"

I see two problems in your code. In your first part, you only sent the encrypted message and the receiver would not decrypt because you didn't send your key to the receiver. The second problem is you use String s = new String(textEncrypted);, you should send the textEncrypted instead of the string because converting bytes to string may lost some information due to encoding.
In your second part, you should call desCipher.init(Cipher.ENCRYPT_MODE, myDesKey); before encryption.

problem solved
encrypt code :
path = chooser.getSelectedFile();
String x = path.toString();
try {
scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
String desKey = "0123456789abcdef";
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes();
desCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] textEncrypted = desCipher.doFinal(text);
String s = new String(textEncrypted);
try {
File statText = new File(x);
FileOutputStream is = new FileOutputStream(statText);
OutputStreamWriter osw = new OutputStreamWriter(is);
Writer w = new BufferedWriter(osw);
w.write(s);
w.close();
}
catch (IOException e3) {
JOptionPane.showMessageDialog(null, "something is wrong with the txt file");
}
}catch(Exception e1)
{
System.out.println("relax and try again");
}
Decrypt code:
path = chooser.getSelectedFile();
String x = path.toString();
try {
Scanner scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
String desKey = "0123456789abcdef";
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes();
desCipher.init(Cipher.DECRYPT_MODE, key);
byte[] textEncrypted = desCipher.doFinal(text);
String s = new String(textEncrypted);
try {
File statText = new File(x);
FileOutputStream is = new FileOutputStream(statText);
OutputStreamWriter osw = new OutputStreamWriter(is);
Writer w = new BufferedWriter(osw);
w.write(s);
w.close();
}
catch (IOException e3) {
JOptionPane.showMessageDialog(null, "something is wrong with the txt file");
}
}catch(Exception e24)
{
System.out.println("relax and try again");
}
Thank you every one.

Related

How to encrypt & decrypt large video file

I would like to store video files in storage that can be accessed only my application. outside the user should not be able to access his video. I tried Encryption & Decryption but the video file is too large (1GB) it takes a lot of time.
Do you have any Idea guys how can I do?
Please find below my Encryption & Decryption Code :
private File sdCardRoot;
private ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sdCardRoot = Environment.getExternalStorageDirectory();
Button encrypt = findViewById(R.id.zip);
Button dencrypt = findViewById(R.id.unzip);
progressBar = findViewById(R.id.progress);
encrypt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
progressBar.setVisibility(View.VISIBLE);
try {
Log.e("file", "try");
encryption();
} catch (Exception e) {
Log.e("file", "catch" + String.valueOf(e));
e.printStackTrace();
}
}
});
dencrypt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
progressBar.setVisibility(View.VISIBLE);
try {
dcryption();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void dcryption() throws Exception {
progressBar.setVisibility(View.VISIBLE);
String password = "javapapers";
// reading the salt
// user should have secure mechanism to transfer the
// salt, iv and password to the recipient
File fileSalt = new File(sdCardRoot, "/salt.enc");
FileInputStream saltFis = new FileInputStream(fileSalt);
byte[] salt = new byte[8];
saltFis.read(salt);
saltFis.close();
// reading the iv
File fileIv = new File(sdCardRoot, "/iv.enc");
FileInputStream ivFis = new FileInputStream(fileIv);
byte[] iv = new byte[16];
ivFis.read(iv);
ivFis.close();
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
256);
SecretKey tmp = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
// file decryption
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
File oldFile = new File(sdCardRoot, "/wp.mp4");
File oldFile1 = new File(sdCardRoot, "/w.des");
FileInputStream fis = new FileInputStream(oldFile1);
FileOutputStream fos = new FileOutputStream(oldFile);
byte[] in = new byte[64];
int read;
while ((read = fis.read(in)) != -1) {
byte[] output = cipher.update(in, 0, read);
if (output != null)
fos.write(output);
}
byte[] output = cipher.doFinal();
if (output != null) {
fos.write(output);
fis.close();
fos.flush();
fos.close();
}
if (fileIv.exists() && fileSalt.exists() && oldFile1.exists()) {
fileIv.delete();
fileSalt.delete();
oldFile1.delete();
}
progressBar.setVisibility(View.GONE);
System.out.println("File Decrypted.");
}
private void encryption() throws Exception {
File oldFile = new File(sdCardRoot, "/w.mp4");
File oldFile1 = new File(sdCardRoot, "/w.des");
Log.e("file", String.valueOf(oldFile));
FileInputStream inFile = new FileInputStream(oldFile);
Log.e("file", String.valueOf(inFile));
// encrypted file
FileOutputStream outFile = new FileOutputStream(oldFile1);
Log.e("file", String.valueOf(outFile));
// password to encrypt the file
String password = "javapapers";
// password, iv and salt should be transferred to the other end
// in a secure manner
// salt is used for encoding
// writing it to a file
// salt should be transferred to the recipient securely
// for decryption
byte[] salt = new byte[8];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(salt);
Log.e("file", "a");
File fileSalt = new File(sdCardRoot, "/salt.enc");
FileOutputStream saltOutFile = new FileOutputStream(fileSalt);
Log.e("file", "b");
saltOutFile.write(salt);
saltOutFile.close();
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536,
256);
SecretKey secretKey = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
// iv adds randomness to the text and just makes the mechanism more
// secure
// used while initializing the cipher
// file to store the iv
Log.e("file", "c");
File fileIv = new File(sdCardRoot, "/iv.enc");
FileOutputStream ivOutFile = new FileOutputStream(fileIv);
Log.e("file", "d");
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
ivOutFile.write(iv);
ivOutFile.close();
//file encryption
byte[] input = new byte[64];
int bytesRead;
while ((bytesRead = inFile.read(input)) != -1) {
byte[] output = cipher.update(input, 0, bytesRead);
if (output != null)
outFile.write(output);
}
byte[] output = cipher.doFinal();
if (output != null)
outFile.write(output);
inFile.close();
outFile.flush();
outFile.close();
if (oldFile.exists()) {
oldFile.delete();
}
System.out.println("File Encrypted.");
}
Use Below Code:
import java.io.File;
import java.io.RandomAccessFile;
public class VideoCrypt {
public static final int REVERSE_BYTE_COUNT = 1024;
public static boolean decrypt(String path) {
try {
if (path == null) return false;
File source = new File(path);
int byteToReverse = source.length() < REVERSE_BYTE_COUNT ? ((int) source.length()) : REVERSE_BYTE_COUNT;
RandomAccessFile f = new RandomAccessFile(source, "rw");
f.seek(0);
byte b[] = new byte[byteToReverse];
f.read(b);
f.seek(0);
reverseBytes(b);
f.write(b);
f.seek(0);
b = new byte[byteToReverse];
f.read(b);
f.close();
return true;
} catch (Exception e) {
return false;
}
}
public static boolean encrypt(String path) {
try {
if (path == null) return false;
File source = new File(path);
RandomAccessFile f = new RandomAccessFile(source, "rw");
f.seek(0);
int byteToReverse = source.length() < REVERSE_BYTE_COUNT ? ((int) source.length()) : REVERSE_BYTE_COUNT;
byte b[] = new byte[byteToReverse];
f.read(b);
f.seek(0);
reverseBytes(b);
f.write(b);
f.seek(0);
b = new byte[byteToReverse];
f.read(b);
f.close();
return true;
} catch (Exception e) {
return false;
}
}
private static void reverseBytes(byte[] array) {
if (array == null) return;
int i = 0;
int j = array.length - 1;
byte tmp;
while (j > i) {
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
j--;
i++;
}
}
}
File types are identified by file extension and file magic. If you want to skip encrypting the file you can edit the file header by changing its magic so that programs can't recognize the type. A "magic" is a few bytes at the start of the file that define its type.

Input length must be multiple of 8 when decrypting with padded cipher

I have a client/server application that encrypts or decrypts a message both on the client-side and server-side. However on decryption I keep getting the following error from the StackTrace
Input length must be multiple of 8 when decrypting with padded cipher
Following is the code from both the Server and Client classes.
The thing is I have tried using ("DES/CBC/PKCS5Padding") and ("UTF-8") but still haven't been able to fix said issue.
Any help would be appreciated thanks?
public class ServerApp {
public static byte[] encrypt(String input, Key k) {
try {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] data = input.getBytes();
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
return null;
}
}
public static String decrypt(byte[] cipher, Key k) {
try {
Cipher cipher1 = Cipher.getInstance("DES");
cipher1.init(Cipher.DECRYPT_MODE, k);
byte[] original = cipher1.doFinal(cipher);
return new String(original);
} catch (Exception ex) {
return null;
//Logger.getLogger(DES.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws NoSuchAlgorithmException {
try {
Key key=KeyGen.getSecretKey();
ServerSocket ser = new ServerSocket(3333);
System.out.println("Server Started");
Socket client = ser.accept();
DataInputStream in = new DataInputStream(client.getInputStream());
DataOutputStream out = new DataOutputStream(client.getOutputStream());
Scanner scan = new Scanner(System.in);
// SecretSocket sc = new SecretSocket(client, KeyGen.getSecretKey());
String serMsg, cliMsg, plain;
// OutputStream sout = sc.getOutputStream();
// InputStream sin = sc.getInputStream();
do {
System.out.print("You say: ");
serMsg = scan.nextLine();
// sout.write(serMsg.getBytes());
// System.out.println("cli server "+sin.read());
byte[] ci = encrypt(serMsg, KeyGen.getSecretKey());
System.out.println("encrypt " +ci.toString());
out.writeUTF(ci.toString());
plain = decrypt(ci, KeyGen.getSecretKey() );
System.out.println("decrypt " + plain);
} while (!serMsg.equals("end"));
client.close();
ser.close();
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class ClientApp {
public static byte[] encrypt(String input, Key k) {
try {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] data = input.getBytes();
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
return null;
}
}
public static String decrypt(byte[] cipher, Key k) {
try {
Cipher cipher1 = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher1.init(Cipher.DECRYPT_MODE, k);
byte[] original = cipher1.doFinal(cipher);
return new String(original);
} catch (Exception ex) {
return null;
//Logger.getLogger(DES.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
try {
Socket s = new Socket("localhost", 3333);
DataInputStream in = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
Scanner scan = new Scanner(System.in);
String serMsg, cliMsg, plain;
do {
System.out.println("server server "+in.readUTF());
serMsg = in.readUTF();
System.out.println("enc: " + serMsg);
plain = decrypt(serMsg.getBytes("UTF-8"), KeyGen.getSecretKey());
System.out.println("Server says: " + plain);
} while (!serMsg.equals("end"));
s.close();
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] data = input.getBytes();
byte[] result = cipher.doFinal(data);
Using DES without IV you are implicitly using DES/ECB/PKCS5Padding.
do not print a byte array directly. Java will output only printable characters. Always encode and decode a byte array when printing (Hex or Base64 are the most common encodings)
Here is an example project
Base64.getEncoder().encodeToString(byteArray)
I hope you are aware DES is considered a weak cipher today and should be used only for backward compatibility.

javax.crypto.BadPaddingException: Given final block not properly padded - DES Decryption

I am trying to decrypt a message on server - the error what I got is
Encryption technique used - DES.
--Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
I am having a very difficult time trying to solve this problem,
any help will be appreciated
class TCPClient {
public static void main(String argv[]) throws Exception {
byte[] sentence, textEncrypted;
String modifiedSentence;
String password;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
password = "Passcode";
byte[] salt = new byte[64];
Random rnd = new Random();
rnd.nextBytes(salt);
byte[] data = deriveKey(password, salt, 64);
// BufferedReader inFromServer = new BufferedReader(new
// InputStreamReader(clientSocket.getInputStream()));
System.out.println("Enter the Data to be transmisted to server\n");
sentence = inFromUser.readLine().getBytes();
SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data));
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, desKey);
textEncrypted = cipher.doFinal(sentence);
outToServer.writeBytes(new String(textEncrypted) + '\n');
clientSocket.close();
}
public static byte[] deriveKey(String password, byte[] salt, int keyLen) {
SecretKeyFactory kf = null;
try {
kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen);
SecretKey key = null;
try {
key = kf.generateSecret(specs);
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return key.getEncoded();
}
}
Server side code
class TCPServer {
public static void main(String argv[]) throws Exception {
String password = null;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
password = "Passcode";
byte[] salt = new byte[64];
Random rnd = new Random();
rnd.nextBytes(salt);
byte[] data = deriveKey(password, salt, 64);
byte [] EncyptedText = inFromClient.readLine().getBytes();
System.out.println("Received Encrypted message " + EncyptedText);
SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data));
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, desKey);
// Decrypt the text
System.out.println("Text Received " + EncyptedText);
byte[] textDecrypted = cipher.doFinal(EncyptedText);
System.out.println("Text Decryted : " + new String(textDecrypted));
}
}
public static byte[] deriveKey(String password, byte[] salt, int keyLen) {
SecretKeyFactory kf = null;
try {
kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen);
SecretKey key = null;
try {
key = kf.generateSecret(specs);
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return key.getEncoded();
}
}
You will lose data doing this:
outToServer.writeBytes(new String(textEncrypted) + '\n');
besides that, it's not necessary. Ciphertext is not really text for modern ciphers, it's binary. And as sockets provide binary InputStreams and OutputStreams there is simply no reason to convert the ciphertext to strings either. All that is required is to convert possible input strings to binary (using the same encoding on both the client and server, of course - UTF-8 is preferred nowadays).

RSA - Encrypt in Android / Decrypt in PHP

I encrypt a word in java and I have trouble decrypting it in php.
here is how I create the keys in android:
public void GenerateAndSaveToFile(){
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
//////////////////////////
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/keys");
myDir.mkdirs();
File file = new File (myDir, "private.key");
FileOutputStream fileout1 = new FileOutputStream(file);
ObjectOutputStream oout1 = new ObjectOutputStream(fileout1);
oout1.writeObject(priv.getModulus());
oout1.writeObject( priv.getPrivateExponent());
oout1.close();
///////////////////////
File file2 = new File (myDir, "public.key");
FileOutputStream fileout2 = new FileOutputStream(file2);
ObjectOutputStream oout2 = new ObjectOutputStream(new BufferedOutputStream(fileout2));
oout2.writeObject(pub.getModulus());
oout2.writeObject( pub.getPublicExponent());
oout2.close();
}
catch (Exception ex){
Exception e = ex;
}
}
here is how I encrypt the word with generated public key in android:
byte[] u1Encrypted = RSAEncrypt(String.valueOf(inputEmail.getText()).getBytes());
public byte[] RSAEncrypt(byte[] data) {
try {
PublicKey pubKey = ReadPublicKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(data);
return cipherData;
}
catch (Exception ex)
{
Exception e = ex;
return null;
}
}
private PublicKey ReadPublicKey() throws IOException {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("public.key");
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
catch (Exception ex)
{
Exception e = ex;
return null;
}
}
then I convert the encrypted string to base64 in android:
String u1EncryptedBase64 = Base64.encodeToString(u1Encrypted, Base64.DEFAULT);
and in php I decode the base64 string:
$encryptedString = base64_decode(u1EncryptedBase64);
get the private key:
$keytmp = fopen("../../../private.key", "r") or die("Unable to open file!");
$key = fread($keytmp,filesize("../../../private.key"));
$res = openssl_get_privatekey($key);
and finally I try to decrypt the string in php:
if (openssl_private_decrypt($encryptedString, $decrypted, $res)) {
echo $decrypted;
}
else
{
echo "problem";
}
and error I get is:
Warning: openssl_private_decrypt(): key parameter is not a valid private key ...
please guide me how to accompolish this task.
thanks
I can show you how i have done encryption in my android and decryption in php. It worked wonderfully fine.May be you can get some help from this. In android the code is like:
final private static String RSA_public_key="MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEApeRuOhn71+wcRtlN6JoW\n" +
"JLrVE5HKLPukFgpMdguNskBwDOPrrdYKP1e3rZMHN9oVB/QTTpkQM4CrGYlstUmT\n" +
"u5nEfdsH4lHRxe3qhi9+zOknWKJCnW4Cq70oITCAK08BIJ/4ZcGM1SUyv1+0u1aB\n" +
"cx6g1aKhthttRjNpck2LBaHVolt7Z4FTb5SdZMwJKRyEv8fuP6yyR0CJGEbQKZKA\n" +
"ODNKyqJ42sVzUQ2AMQIWdhkFdAFahKCL4MChGvKU6F20cHdvokyxXJjU3sZobjNf\n" +
"i+8FzH9hd7y8kmi4o3AKP69p5asgflXoXHpo135i3NzZqlNJ+Bs9pY+90u9iLScp\n" +
"JwIBAw==";
static String enccriptData(String txt)
{
String encoded = "";
byte[] encrypted = null;
try {
byte[] publicBytes = Base64.decode(RSA_public_key, Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); //or try with "RSA"
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
encrypted = cipher.doFinal(txt.getBytes());
encoded = Base64.encodeToString(encrypted, Base64.DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
return encoded;
}
I have paste that encoded string that is returned in the above function in below $string. This is the code for php:
<?php
$string="W39VlV1Q96QzDIR/jINzaEL7rh2Z+Z90uxJ1DtaSfkVKzIgt2TIkxsuRY+A2icwPtTdq6+9j1Xb009KT+ck2KD+dot3wPL5UaHqApbZSi6UZan/nDbFCNJdffTlTWsPS2ThEefeMMSs8HE2ORSt42D8cxYlogOvkvlLr60cHYKwfC1itLSqPuYR+C/gPAf6yCteLbj//EkJp8TemlmPi0eSsH492FgrmBqiTOS4LzpzsPFpSI4KJbuM2dvqp5jkt7MnpR1laILmyC37fA5XPUQmEQChoG5eSbMxqO7SPboYC1BH9ATy6uTS1MGXGDzJ2FSJ41MMRV1Ul/4UNFVA8Ng==";
$encryptedString = base64_decode($string);
$key="-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCl5G46GfvX7BxG
2U3omhYkutUTkcos+6QWCkx2C42yQHAM4+ut1go/V7etkwc32hUH9BNOmRAzgKsZ
iWy1SZO7mcR92wfiUdHF7eqGL37M6SdYokKdbgKrvSghMIArTwEgn/hlwYzVJTK/
X7S7VoFzHqDVoqG2G21GM2lyTYsFodWiW3tngVNvlJ1kzAkpHIS/x+4/rLJHQIkY
RtApkoA4M0rKonjaxXNRDYAxAhZ2GQV0AVqEoIvgwKEa8pToXbRwd2+iTLFcmNTe
xmhuM1+L7wXMf2F3vLySaLijcAo/r2nlqyB+VehcemjXfmLc3NmqU0n4Gz2lj73S
72ItJyknAgEDAoIBAG6YSXwRUo/yvYSQ3psRZBh8jg0L3B39GA6xiE6yXnbVoAiX
8nPkBtTlJR5iBM/muK/4DN8QtXerHLuw8yOGYn0RLak8r+w2i9lJRwQfqd3wxOXB
gb5JVx0oxWt1qseKAMBqpZkrszjDdyo/zdI5q6IUazkXFnlnni7M8PbeXK5q0PE6
0XclC1W79jX71D8d24SITAfXDqaXOwObSn9dadw1gsxx8fPd6Fr7ZTS0AddxJZN2
jNK14xkv2rkxdP1W529gnCVQUhju5SPJS5QwphI7KyfH7wTHnBOhbhp3FpaVKPz0
biLwZ6D0xgR6reZofz+t1cvDOha54wC4ZZYJyTsCgYEA0blJn8zxAHDSj8z/01zz
dc1qdYfdlf9gEWgr+APS9XSowGg+CdQN2W0XwySlpPoMZyCKM/aH0DNcl11yynpL
Mkm5MU2V2T+VKWXwUNHrGXSVRJkgLu+iD1Pt0oGPfS9qRYydG5TBjQEVrBrh4Jtk
KdsMBA82mgxEdFqtERbTpi0CgYEAyn85oWfYwf4oHEbSd218RauRBqwMhk39nyqx
6Gaza/k6Ri+5hBjqvVt8pT1Obrji5fZFU1IH5wecQae1mvIQJv+tVBy+XPedU8Mo
Jj3/TPwBAHezTADvQyEIwPot6y5lZt2fX7Urv+n1k7XkfWfb8O/ChTc/zHc0dPct
uLVE1SMCgYEAi9Dbv932AEs3CoiqjOiiTojxo6/pDqpAC5rH+q03Tk3F1ZrUBo1e
kPNlLMMZGKay72sGzU8FNXeTD5Oh3FGHdtvQy4kOkNUOG5lK4IvyEPhjgxDAH0ps
Cjfz4au0/h+cLl2+EmMrs1YOcryWlbztcTyyrV95vAgtouceC2SNGXMCgYEAhv97
wO/l1qlwEtnhpPOoLnJgrx1drt6pFMchRZnM8qYm2XUmWBCcfjz9w340SdCXQ/mD
jOFamgUS1m/OZ0wKxKpzjWh+6KUTjSzFbtP/iKgAqvp3iACfghYF1fwenMmY7z5q
P84dKpv5DSPtqO/n9fUsWM9/3aTNo09z0HjYjhcCgYEAoN+1/ZzonPWDIY/u+7bW
e8BkcuBVpMZe7qBYHeVix89yvyuVE+erKqurnG7fN7YIDX8V1OcVP+qHw8fJNQKL
wd03nNIIJyTPXodgty3HYjBUe8fVn/8P+JOv2U7bJCkUGlFeyZIMZWEsYd8t5794
3fotiYXOUug9bFtnGHRyY7I=
-----END PRIVATE KEY-----";
openssl_private_decrypt($encryptedString, $decrypted, $key);
$string1=$decrypted;
echo $string1;
?>
The private and public keys are made for each other.

Read public key from file

i am trying to verify a file with my java program. I have no idea what i am doing wrong, all the solutions i found does not work.
Here is my code:
public boolean pruefeSignatur(File file, File signatur, File publicKey) {
boolean verifies = false;
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// encode public key bytes
FileInputStream keyfis = new FileInputStream(publicKey);
byte [] encKey = new byte[keyfis.available()];
keyfis.read(encKey);
keyfis.close();
// key specification
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
// conversion
KeyFactory keyFactory = KeyFactory.getInstance(pubKeySpec.getFormat());
// generate publicKey
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
// input signature bytes
FileInputStream sigfis = new FileInputStream(signatur);
byte[] sigToVerify = new byte[sigfis.available()];
sigfis.read(sigToVerify);
sigfis.close();
// initialize the signature
Signature sig = Signature.getInstance("RSA");
sig.initVerify(pubKey);
// supply signature object with the data to be verified
FileInputStream datafis = new FileInputStream(file);
BufferedInputStream bufin = new BufferedInputStream(datafis);
byte[] buffer = new byte[1024];
int len;
while(bufin.available() != 0) {
len = bufin.read(buffer);
sig.update(buffer, 0, len);
}
bufin.close();
//verify signature
verifies = sig.verify(sigToVerify);
} catch (Exception e) {
e.printStackTrace();
}
return verifies;
}
With this code i get the exception:
java.security.spec.InvalidKeySpecException: java.lang.ClassCastException: org.bouncycastle.asn1.DERUnknownTag cannot be cast to org.bouncycastle.asn1.ASN1Object
When i use Base64, for example:
Base64 decoder = new Base64();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(decoder.decode(encKey));
I get the exception:
java.security.spec.InvalidKeySpecException: java.io.IOException: unexpected end-of-contents marker
Another solution i found was changing it to:
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
// conversion
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
But then i get the exception:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
I made my keys with Gpg4win and Kleopatra.
Edit:
Now I do not get an error, but the function always returns false. So I am not sure if everything is right.
public boolean pruefeSignatur(File file, File signaturFile, File publicKeyFile) throws IOException {
boolean verifies = false;
FileInputStream keyfis = null;
DataInputStream keydis = null;
FileInputStream sigfis = null;
DataInputStream sigdis = null;
FileInputStream datafis = null;
DataInputStream datadis = null;
try {
// add provider
Security.addProvider(new BouncyCastleProvider());
// encode public key bytes
keyfis = new FileInputStream(publicKeyFile);
keydis = new DataInputStream(keyfis);
byte[] keyBytes = new byte[(int) publicKeyFile.length()];
keydis.readFully(keyBytes);
keyfis.close();
keydis.close();
// key specification
String modulusBase64 = new String(keyBytes);
Base64 b64 = new Base64();
String exponentBase64 = "65337"; //festgelegte Zahl http://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(1, b64.decode(modulusBase64)), new BigInteger(1, b64.decode(exponentBase64)));
// conversion
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// generate publicKey
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
// read signature
sigfis = new FileInputStream(signaturFile);
sigdis = new DataInputStream(sigfis);
byte[] sigBytes = new byte[(int) signaturFile.length()];
sigdis.readFully(sigBytes);
sigfis.close();
sigdis.close();
// initialize the signature
Signature sig = Signature.getInstance("RSA");
sig.initVerify(publicKey);
// supply signature object with the data to be verified
datafis = new FileInputStream(file);
datadis = new DataInputStream(datafis);
byte[] dataBytes = new byte[(int) file.length()];
datadis.readFully(dataBytes);
/*
int len;
while(datadis.available() != 0) {
len = datadis.read(dataBytes);
sig.update(dataBytes, 0, len);
}
*/
datadis.close();
datafis.close();
sig.update(dataBytes);
//verify signature
verifies = sig.verify(sigBytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (keyfis != null) {
keyfis.close();
}
if (keydis != null) {
keydis.close();
}
if (sigfis != null) {
sigfis.close();
}
if (sigdis != null) {
sigdis.close();
}
if (datafis != null) {
datafis.close();
}
if (datadis != null) {
datadis.close();
}
}
return verifies;
}
Finally i have a solution:
InputStream inSig = PGPUtil.getDecoderStream(new FileInputStream(signaturFile));
//ArmoredInputStream inSig = new ArmoredInputStream(new FileInputStream(signaturFile));
JcaPGPObjectFactory objFactory = new JcaPGPObjectFactory(inSig);
PGPSignatureList signatureList = (PGPSignatureList) objFactory.nextObject();
PGPSignature signature = signatureList.get(0);
InputStream keyIn = PGPUtil.getDecoderStream(new FileInputStream(publicKeyFile));
//ArmoredInputStream keyIn = new ArmoredInputStream(new FileInputStream(publicKeyFile));
JcaPGPPublicKeyRingCollection pgpRing = new JcaPGPPublicKeyRingCollection(keyIn);
PGPPublicKey publicKey = pgpRing.getPublicKey(signature.getKeyID());
byte[] bytePublicKeyFingerprint = publicKey.getFingerprint();
char[] publicKeyFingerprintHexArray = org.apache.commons.codec.binary.Hex.encodeHex(bytePublicKeyFingerprint);
String publicKeyFingerprintHex = new String(publicKeyFingerprintHexArray);
signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);
FileInputStream in = new FileInputStream(file);
byte[] byteData = new byte[(int) file.length()];
in.read(byteData);
in.close();
signature.update(byteData);
if (signature.verify() && publicKeyFingerprintHex.equals(fingerprint)) {
return true;
} else {
return false;
}

Categories