Decrypting with same public key used for encryption in Java - java

I have a public key which is used to encrypt some binary data. How can I write the code that can decrypt this data with the same public key ?

You can't - the whole point about public/private-key-cryptography like RSA is that when you encrypt some data using a public key you can only decrypt it using the matching (!) private key. So without the proper private key you won't be able to recover your AES-key and you won't get back to your cleartext.

Related

Convert a key string to a SecretKeys object in tozny/java-aes-crypto

I'm using java-aes-crypto for encrypting strings in android. After generating key using this code
AesCbcWithIntegrity.SecretKeys keys = AesCbcWithIntegrity.generateKey();
and I'm saving it as String(.toString()) in a file and after that I'm trying to retrieve it from that file and convert it to the same object. How can I do that?
Use the following static method in the AesCbcWithIntegrity class (link):
/**
* An aes key derived from a base64 encoded key. This does not generate the
* key. It's not random or a PBE key.
*
* #param keysStr a base64 encoded AES key / hmac key as base64(aesKey) : base64(hmacKey).
* #return an AES and HMAC key set suitable for other functions.
*/
public static SecretKeys keys(String keysStr) throws InvalidKeyException {...}
It properly parses the previously serialized keys into the encryption key and the integrity key.
On going through the link,one can see that you need to use the following code to convert the encrypted String into the desired one.
//Use the constructor to re-create the CipherTextIvMac class from the string:
CipherTextIvMac cipherTextIvMac = new CipherTextIvMac (cipherTextString);
String plainText = AesCbcWithIntegrity.decryptString(cipherTextIvMac, **keys**);
The keys is the same key that was used while encryption.
As you can see, you need to store the key to decrypt it. The link also provides the precaution to store the key
Once you've generated a random key, you naturally might want to store
it. This may work for some use cases, but please be aware that if you
store the key in the same place that you store the encrypted data,
your solution is not cryptographically sound since the attacker can
just get both the key and the encrypted text. Instead, you should use
either the Keystore infrastructure or consider generating the key from
a passphrase and using that to encrypt the user data.
If despite the above you still want to store the key, you can convert
the keys to a string using the included functions and store them in
preferences or SQLite.

Encrypt 5-10MB file with private key and decrypt with public key

I am trying to encrypt a file using a private key via RSA and then decrypt it using the public key in Java. I know very well that this is the reverse use case of how RSA is normally used with private/public key pairs.
My objective is to take a file, encrypt it on one system using a private key, and then decrypt it on a different system using the public key. I plan to distribute the public key so that anyone can read the file. What I am trying to prevent is from anyone being able to create the file.
I have found these C header functions and them implemented in PHP so i know what I am trying to do is possible
int RSA_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
int RSA_public_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
How can I achieve the same behavior in Java? I keep googling and searching for things but maybe I am just not using the right words. Everything keeps coming up showing me how to encrypt with public and decrypt with private when I am trying to do the opposite.
The file i want to encrypt ranges from 5-10MB in size.
Thanks!
If you want identify the person who owns the private key, and therefore owns the file, I guess the process you are looking for is "digital signature" (and not encryption), as comments #EJP
Digest the file with a hashing algorithm like SHA-256. Creates a summary of a few bytes "hash"
Sign the hash using the RSA private key. This is called the "signature"
Send the file and the signature to a third party. They can verify the signature using the public key. If signature match then you can ensure the identity of the sender of the message and that has not been altered
In this case case file is not encrypted, is hashed and signed.
If you need to encrypt to hide the content, then you can't use RSA, because message size is limited by the length of the key. So 10mb is too big. In this case I suggest to use en encryption algorithm like AES to encrypt the content.
The third party will need the AES decryption key. Generate it before this or encrypt the AES key with a RSA public key of the third party using RSASA-OAEP padding (according link provided by #Maarten Bodewes)
Generating a digital signature
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(privateKey);
sig.update (data)
byte[] signature = sig.sign();
Verifiying the signature
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(publicKey);
sig.update(data);
boolean verifies = sig.verify(signature);

RSA encryption in Java, decrypt in PHP

Assume I have the following Java code to generate a Public-private keypair:
KeyPairGenerator generator = KeyPairGenerator.getInstance ("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
generator.initialize (1024, random);
KeyPair pair = generator.generateKeyPair();
RSAPrivateKey priv = (RSAPrivateKey)pair.getPrivate();
RSAPublicKey pub = (RSAPublicKey)pair.getPublic();
// Sign a message
Signature dsa = Signature.getInstance("SHA1withRSA");
dsa.initSign (priv);
dsa.update ("Hello, World".getBytes(), 0, "Hello, World".length());
byte[] out = dsa.sign();
/* save the signature in a file */
FileOutputStream sigfos = new FileOutputStream("sig");
sigfos.write(out);
sigfos.close();
How would one go about and decrypt the file "sig" in PHP? I've read the post: https://stackoverflow.com/a/1662887/414414 which supplies a function to convert a DER file to PEM (Assume I also save the public key from Java).
I have tried something like:
$key = openssl_pkey_get_public ("file://pub_key.pem");
$data = null;
openssl_public_decrypt ( file_get_contents ("sig"), $data, $key);
echo $data, "\n";
It successfully decrypts the message, but it is many weird characters.
Our scenario is a Java client that is sending messages to a PHP server, but encrypts the data with a private key. PHP knows about the public key, which it should use to decrypt and validate the message.
I've read a lot of posts regarding this issue here on SO, but I've come to realize that this is a bit specific issue, especially if there's different algorithms in use, etc. So sorry if this may be a duplicate.
Any feedbacks are greatly appreciated!
an "RSA signature" is usually more than just "encrypt with private key, decrypt with public key", since Public key protocols like PKCS#1 also specify padding schemes, and all signature schemes will encrypt a digest of the message, instead of the full message. I cannot find any documentation if java's signature scheme uses the signature padding scheme specified in PKCS#1, but my suspicion is that it is.
If it is, you will instead want to use the openssl_verify method in PHP, documented here. This will return a 0 or 1 if the signature is invalid or valid, respectively.
In the event that Java does not use a padding scheme, your issue is that the data encrypted in the signature is a hash of the message, instead of the message itself (you can see in the Java code that it uses the SHA-1 hash algorithm). So on the PHP side, you will need to take the sha1 hash of your message using the sha1 method with $raw_output set to true, and compare those strings to ensure your message is valid.
From the snippet
$key = openssl_pkey_get_public ("file://pub_key.pem");
It looks like you're referencing the public key, which would be the wrong one to decrypt. Double check ?

RSA keyczar and js

I've implemented a security system in my app with RSA.
I've generated the public and private keys using Keyczar Tool. Using just keyczar I can encrypt with public key and decrypt with private key with no problems at all.
I want to encrypt some data in JS and then pass it to Java. For this I'm trying to use this library (https://github.com/ziyan/javascript-rsa) but I'm not being able to encrypt the data or at least not encrypting the data correctly (it's bigger than with keyczar).
How can I encrypt with this tool using my public key? Can anyone help me?
There is not a javascript client for keyczar, so if you want to produce ciphertext consumable by keyczar.
Look at the keyczar public key format you will need to provide the public key info from your server to your javascript encryptor.
http://code.google.com/p/keyczar/wiki/RsaPublicKey
Alternatively, it looks like your javascript library will read PEM format. You can use the KeyczarTool to export your public key in PEM format with the export.
Look at the Keyczar ciphertext format for rsa
http://code.google.com/p/keyczar/wiki/CiphertextFormat
You'll need to prepend the header to your ciphertext generate with the javascript.
Technically you need to produce a keyhash to append a proper header, but a given header will always be identical for a given key regardless of the ciphertext, so you could just provide it with your public key generated by the java keyczar code.

how to load an rsa privated key encrypted with des in java

in my job i was assigned a task in which i have to programmatically load a private and public keys from files and then store them in a .jks file,the private key was generated using openssl, its an rsa des encrypted key in der format,i have no problem loading the public key, however,i haven't found a way to load the private key in its original form, the only way i found consist in decrypt the key and then convert it to a pk8 file, its there any other way to do it without decrypting the private key?
OpenSSL's standard way to save keys is to use PEM format (PEM header and footer and base64-encoded DER key inside). Private key is additionally encrypted (encryption algorithm is specified in header). JKS doesn't use DER for encryption of the private key, so you can't just take the encrypted DER sequence and put it to JKS. To add the keypair to JKS you need to get both public and private key in DER format and the private key must be decrypted.

Categories

Resources