Openssl encryption [Kotlin] [Android] (PHP) - java

Using api I have to connect to PHP project with encrypted login and password in Kotlin.
I need to use the same secret password as I use in PHP, but have problem with generating Secret Key by following line:
val sk = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8),"AES_256") //here exception is throwing
val iv = IvParameterSpec(secretKey.substring(0, 16).toByteArray(Charsets.UTF_8))
c.init(opmode, sk, iv)
That's my secret key:
ksjdg*&%$dfgh"{##!vcfkslc,.a/dcfxcsw345,45654gfdsgtrasd;fsdjf]}{O0-xfvbgdfeh=
The problem is that exception is throwing about unsupported key size. I got it.
But why using PHP and doing the same, using the same key, don't have any errors? :
$encryptionKey = `ksjdg*&%$dfgh"{##!vcfkslc,.a/dcfxcsw345,45654gfdsgtrasd;fsdjf]}{O0-xfvbgdfeh=`
$encrypted = openssl_encrypt($value, $encryptionMethod, $encryptionKey, 0, $iv);
What should do in Kotlin with my key to have it worked?

Related

Encrypting files with Java 7 at local using AWS KMS Data Keys

I am trying to encrypt/decrypt local files with AWS KMS DataKey but I don't know what to use to do it.
I have already generated the DataKey from AWS KMS (receiving the Plaintext Key and the Encrypted Key). Now it's supposed I have to use the Plaintext key to encrypt the file, store the Encrypted key with the Final Encrypted file and delete the Plaintext key.
How do I encrypt a file in Java 7 using that Plaintext Key? I mean, there are several ways to do it but which is the most effective and secure with AES_256 cipher I request to AWS KMS to get the keys?
//AWS KMS requesting data key
GenerateDataKeyRequest dataKeyRequest = new GenerateDataKeyRequest()
dataKeyRequest.setKeyId(keyId)
dataKeyRequest.setKeySpec("AES_256")
GenerateDataKeyResult dataKeyResult = awskmsClient.generateDataKey(dataKeyRequest)
ByteBuffer plaintextKey = dataKeyResult.getPlaintext()
ByteBuffer encryptedKey = dataKeyResult.getCiphertextBlob()
I cannot use AWS Encryption to do that (even it would be easier) because o Java 7 version

RSA public key generation issue (PHP/Java integration)

I have one server and one client.
Client might be in different technologies like java , php.
server code is written in java.
What I am doing in server is, get exponent and modulus bytes of client public key and generate public key of client.
To generate client public key I am using the code below:
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulusBigInt,exponentBigInt);
keyFactory = KeyFactory.getInstance("RSA", "BC");
RSAPublicKey clientPublicKey = (RSAPublicKey) keyFactory.generatePublic(spec);
To encrypt data using client public key I am using below code:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, clientPublickey);
scrambled = cipher.doFinal(buffer);
Server Information
I have implemented RSA-1024 to encrypt AES key.
I am using RSA/ECB/PKCS1Padding algorithm. and I have also make sure that all clients have also consider 1 padding in their code.
Client - 1 (Java)
If client is also made in java than public key is successfully generated from exponent and modulus of client public key.
I am using the code below to generate key pair of client RSA key..
keyPairGene = KeyPairGenerator.getInstance("RSA");
keyPairGene.initialize(1024);
KeyPair keyPair = keyPairGene.genKeyPair();
RSAPublicKey clientPublickey = (RSAPublicKey) keyPair.getPublic();
Client -2 (php)
Now the problem is if client is in php .. than public key is successfully generated but when I try to encrypt using that public key at that time bad padding exception occurs when I have used default provider in server.
I am using bellow code to generate key pair of client RSA key..
$options = array('private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'config' => realpath(__DIR__) . '/openssl.cnf');
#Generates New Private / Public Key Pair
$pkGenerate = openssl_pkey_new($options);
#Get Client Private Key
openssl_pkey_export($pkGenerate, $PrivateKey, NULL, $options);
#Get Client Public Key
$keyData = openssl_pkey_get_details($pkGenerate);
Than I have tried BC provider ... It gives me the exception below:
org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.
I am not getting what is the problem occurs when I am trying to generate public key from exponent and modulus when client is in php...
if client is in java than its no issues.... and works perfectly..
Any type of help is welcome...
Note:
What I have observed from debugging code is ,
client's public key modulus byte's bit length at server side is varies between 1020 to 1023... it never reaches at 1024 though we have define size as 1024.
Still don't get what exactly the problem is...
but I have implemented work around for it...
I got stuck in generating public key of client using exponent and modulus.
So now I have used one standard format of public key certificate - DER & PEM.
What I did is, generated DER or PEM from PHP side using bellow code,
$options = array('private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'config' => realpath(__DIR__) . '/openssl.cnf');
#Get Client Public Key
$keyData = openssl_pkey_get_details($pkGenerate);
$clientPublicKey = $keyData['key'];
$this->clientData['clientPublicKeyPEM'] = $keyData['key'];
And then send that generated PEM to Server (Java).
And at server side I have developed bellow code to regenerate Public key from POM string.
KeyFactory keyFactory=KeyFactory.getInstance("RSA");
byte[] pubKeyBits = Base64.decodeBase64(clientPublickeyView.getModulusBytes());
PublicKey pubKey=keyFactory.generatePublic(new X509EncodedKeySpec(pubKeyBits));

creating HMAC in Nodejs with base64 encoded secret

I'm trying to generate HMAC of a message. The algo for HMAC generation is SHA256. The issue is i have a base64 encoded key(shared secret). How can i decode this secret to get the required hmac
Sample code:
var hmac = require('crypto').createHmac('SHA256', "SOME_BASE64_ENCODED_SHARED_SECRET").update("MESSAGE").digest('base64');
This hmac is sent to a java service. The way it does hmac generation is as follows:
Mac mac = Mac.getInstance("HmacSha256");
SecretKey sharedKey = new SecretKeySpec(Base64.getDecoder().decode("SOME_BASE64_ENCODED_SHARED_SECRET"), "TlsPremasterSecret");
mac.init(sharedKey);
byte[] messageBytes = "MESSAGE".getBytes("UTF-8");
byte[] expectedHmac = mac.doFinal(messageBytes);
String hmac = Base64.getEncoder().encodeToString(expectedHmac));
Now, the HMACs generated by my nodejs code does not match with Java service code. How do i solve this problem?
The base64-encoded secret needs to be decoded before passing it to crypto.createHmac():
var secret = Buffer.from('SOME_BASE64_ENCODED_SHARED_SECRET', 'base64');
var hmac = require('crypto').createHmac('SHA256', secret)
.update('MESSAGE')
.digest('base64');
//include crypto
var crypto = require('crypto');
var yourMessage = 'your signature to be hashed using HMAC SHA256';
var sharedSecret = 'your shared secret key';
//generate hmac sha256 hash
var hmacSignature = crypto.createHmac('SHA256', new Buffer(sharedSecret, 'base64')).update(yourMessage).digest('base64');
Above worked for me too.
Note: HMAC SHA256 is hash value, it cannot be decoded. Based on unique secret and unique message (generally date-time is used) a unique hash is created. Client sends this hash value and server generates its own hash value using same algorith, if both hash value match then authorization is successful.
I spent lot of time troubleshooting this. Hope above info help others.

Php AES ECB encryption java decryption not working

I am writing an android application which connects to php web service. Actually there is a similar ios application working well, I am cloning it.
Between php and ios they use AES encryption/decryption. It works well. But with java encryption is ok but decryption is not working.Java encrypts and php understands but when php makes the encryption my java code is not good enough. I am writing below codes.
can anyone guide me, help me ?
PHP encryption :
echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
outputstring,
MCRYPT_MODE_ECB,
nil));
IOS decryption :
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
kCCOptionECBMode,
(const void *)[symmetricKey bytes],
kCCKeySizeAES256,
nil,
(const void *) [plainText bytes],
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes
);
Java Decryption -NOT WORKING WELL- Not working means, using same data, same encryption, same key i can not get same output.
SecretKeySpec skey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance(AES/ECB/NoPadding, "BC");
cipher.init(Cipher.DECRYPT_MODE, skey);
result = decrypt(cipher, input);
I am looking an ideal solution for java decryption ? All helps are welcome ?

Decrypting encrypted assertion using SAML 2.0 in java using OpenSAML

I have a problem while trying to decrypt encrypted assertion using SAML 2.0. The library I am using is OpenSAML Java libraries 2.5.2.
The encrypted assertion looks like this:
<EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<enc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns:enc="http://www.w3.org/2001/04/xmlenc#">
<enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
</e:EncryptionMethod>
<KeyInfo>
<o:SecurityTokenReference
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
1.0.xsd">
<o:KeyIdentifier
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-
1.1#ThumbprintSHA1"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-
message-security-1.0#Base64Binary">
1H3mV/pJAlVZAst/Dt0rqbBd67g=
</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>
... ENCRYPTED KEY HERE ...
</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
</KeyInfo>
<enc:CipherData>
<enc:CipherValue>
... ENCRYPTED ASSERTIONS HERE ...
</enc:CipherValue>
</enc:CipherData>
</enc:EncryptedData>
</EncryptedAssertion>
I did convert my private key that is in PEM format to pkcs8 format using the following openssl command:
openssl pkcs8 -topk8 -nocrypt -inform PEM -in rsa_private_key.key -outform DER -out rsa_private_key.pk8
I am then ready to try to decrypt the encrypted assertion. Here is my Java code:
...
// Load the XML file and parse it.
File xmlFile = new File("data\\token.xml");
InputStream inputStream = new FileInputStream(xmlFile);
Document document = parserPoolManager.parse(inputStream);
Element metadataRoot = document.getDocumentElement();
// Unmarshall
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
EncryptedAssertion encryptedAssertion = (EncryptedAssertion)unmarshaller.unmarshall(metadataRoot);
// Load the private key file.
File privateKeyFile = new File("data\\rsa_private_key.pk8");
FileInputStream inputStreamPrivateKey = new FileInputStream(privateKeyFile);
byte[] encodedPrivateKey = new byte[(int)privateKeyFile.length()];
inputStreamPrivateKey.read(encodedPrivateKey);
inputStreamPrivateKey.close();
// Create the private key.
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
RSAPrivateKey privateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);
// Create the credentials.
BasicX509Credential decryptionCredential = new BasicX509Credential();
decryptionCredential.setPrivateKey(privateKey);
// Create a decrypter.
Decrypter decrypter = new Decrypter(null, new StaticKeyInfoCredentialResolver(decryptionCredential), new InlineEncryptedKeyResolver());
// Decrypt the assertion.
Assertion decryptedAssertion;
try
{
decryptedAssertion = decrypter.decrypt(encryptedAssertion);
}
...
Running this code always results as being unable to decrypt the assertion. I do get the following errors:
5473 [main] ERROR org.opensaml.xml.encryption.Decrypter - Error decrypting encrypted key
org.apache.xml.security.encryption.XMLEncryptionException: Key is too long for unwrapping
Original Exception was java.security.InvalidKeyException: Key is too long for unwrapping
at org.apache.xml.security.encryption.XMLCipher.decryptKey(Unknown Source)
at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:681)
at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:612)
at org.opensaml.xml.encryption.Decrypter.decryptUsingResolvedEncryptedKey(Decrypter.java:762)
at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:513)
at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:440)
at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:401)
at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)
at DecrypterTool.main(DecrypterTool.java:121)
java.security.InvalidKeyException: Key is too long for unwrapping
at com.sun.crypto.provider.RSACipher.engineUnwrap(DashoA13*..)
at javax.crypto.Cipher.unwrap(DashoA13*..)
at org.apache.xml.security.encryption.XMLCipher.decryptKey(Unknown Source)
at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:681)
at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:612)
at org.opensaml.xml.encryption.Decrypter.decryptUsingResolvedEncryptedKey(Decrypter.java:762)
at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:513)
at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:440)
at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:401)
at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)
at DecrypterTool.main(DecrypterTool.java:121)
5477 [main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedKey, valid decryption key could not be resolved
5477 [main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedData using either EncryptedData KeyInfoCredentialResolver or EncryptedKeyResolver + EncryptedKey KeyInfoCredentialResolver
5478 [main] ERROR org.opensaml.saml2.encryption.Decrypter - SAML Decrypter encountered an error decrypting element content
org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData
at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:524)
at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:440)
at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:401)
at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)
at DecrypterTool.main(DecrypterTool.java:121)
I really don't know what I'm doing wrong in this case. I converted my private key to pkcs8, I loaded my SAML XML data and unmarshalled it into the valid type (EncryptedAssertion) and I created a decrypted based on my private key.
Is it possible that it is related to the oaep format for RSA? I'm using the default java cryptography library.
Thanks!
For those of you who will get this problem, it was related to the fact that the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files was not installed and it was not letting me use encryption better than AES-128. Replacing the policy files with the JCE policy files, I was able to successfully decrypt my encrypted assertion.
Agree with #thwalrusnp. Just wanted to add the exact location from where you can download the policy jars.
Found it on the answer to Error while decrypting assertion sent from IDP
This happens due to limitation of cryptography strength in default
distribution of Java Runtime Environment.
Download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files (for Java 7) (for Java 8)
Extract zip archive and find there local_policy.jar and US_export_policy.jar.
Replace your JRE version of these files under $JAVA_HOME/jre{version_number}/lib/security/ with downloaded ones.
Restart JRE process, if any running. Now you can use longer keys.

Categories