Caused by: java.lang.IllegalArgumentException: Invalid salt revision - java

i have create an university project with Java And Symfony when the user register from my java app he can login with both java and symfony , but the contrary it is impossible , it only login from symfony and it display to me this error in java
Caused by: java.lang.IllegalArgumentException: Invalid salt revision
Cryptage Methode : Bcrypt
Security.yml Symf
App\Entity\Utilisateur:
algorithm: bcrypt
encode_as_base64: false
iterations: 1
Utilisateur entity
/**
* Returning a salt is only needed, if you are not using a modern
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
*
* #see UserInterface
*/
public function getSalt(): ?string
{
return null;
}
JAVA
Login Method
if (rs.getString("email").equals(t.getEmail()) && BCrypt.checkpw(t.getMotpasse(), rs.getString("motpasse")) == true) {
if (rs.getString("activated").equals("Active")) {
idUser = rs.getInt("idU");

For more information on this error check BCrypt.checkpw() Invalid salt version exception
I would suggest you start to debug the following piece of your code:
BCrypt.checkpw(t.getMotpasse(), rs.getString("motpasse"))
Check in your database what the value for the hashed password is.
Does it match the expected value of $xy$... where xy should be 2a, 2b, 2y or similar.
Check in your Java code what the values of password t.getMotpasse() and hashed password rs.getString("motpasse") are; log them/debug the code.
Make sure to check the documentation, that you are providing the arguments of checkpw in the correct order (plain, hashed and not hashed, plain).
But I suspect that your PHP library generates a newer salt version (revision) that your current java library does not support. See for example https://github.com/djmdjm/jBCrypt/issues/2
Some code examples that i could find throw this exception when the salt version is not 2a, which would explain why generated salts from Java do work, but from Php don't.
In that case you will either have to:
make sure the PHP code generates salt versions 2a
upgrade/change the Java BCrypt library to a version that supports the newer salt revision

Related

SecretKeyFactory Not Available (Jasypt)

I am trying to encrypt a string using Jasypt 1.9.3 and my JDK version is 1.8.0_281.
This is the code I am have written:
Security.setProperty("crypto.policy", "unlimited");
if (pooledPBEStringEncryptor == null) {
pooledPBEStringEncryptor = new PooledPBEStringEncryptor();
pooledPBEStringEncryptor.setPassword(encryptionKey);
pooledPBEStringEncryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES256");
pooledPBEStringEncryptor.setPoolSize(4);
pooledPBEStringEncryptor.setSaltGenerator(new RandomSaltGenerator());
}
encrypted = pooledPBEStringEncryptor.encrypt(cValue);
But when I run it, I get the error
Exception in thread "main" java.lang.RuntimeException: Security Error in doEncrypt: org.jasypt.exceptions.EncryptionInitializationException: java.security.NoSuchAlgorithmException: PBEWITHHMACSHA512ANDAES256 SecretKeyFactory not available
I ran the AlgorithmRegistry.getAllPBEAlgorithms() and my output is:
PBEWITHHMACSHA1ANDAES_128, PBEWITHHMACSHA1ANDAES_256, PBEWITHHMACSHA224ANDAES_128, PBEWITHHMACSHA224ANDAES_256, PBEWITHHMACSHA256ANDAES_128, PBEWITHHMACSHA256ANDAES_256, PBEWITHHMACSHA384ANDAES_128, PBEWITHHMACSHA384ANDAES_256, PBEWITHHMACSHA512ANDAES_128, PBEWITHHMACSHA512ANDAES_256, PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_128, PBEWITHSHA1ANDRC2_40, PBEWITHSHA1ANDRC4_128, PBEWITHSHA1ANDRC4_40
When I use the algorithm PBEWITHHMACSHA256ANDAES_256 I get a different error.
Exception in thread "main" java.lang.RuntimeException: Security Error in doEncrypt: org.jasypt.exceptions.EncryptionOperationNotPossibleException
I am a little lost as to what to do.
I have downloaded the unlimited policy jars from Oracle and saved them in JAVA_HOME\jre\lib\security\ folder. And I am on Windows.
The code lacks the specification of the IV generator with setIvGenerator(), e.g.:
pooledPBEStringEncryptor.setIvGenerator(new RandomIvGenerator());
By default, NoIvGenerator is used, which causes the exception because the algorithm applies the CBC mode, which requires an IV.
The default salt generator, by the way, is RandomSaltGenerator, so this would not necessarily need to be specified with setSaltGenerator().
The PooledPBEStringEncryptor#encrypt() method returns the Base64 encoded concatenation of salt (16 bytes), IV (16 bytes) and ciphertext.
The exception org.jasypt.exceptions.EncryptionOperationNotPossibleException is a general exception that is generated in many error situations and is therefore not very meaningful, see here. This includes e.g. the missing of the JCE Unlimited Strength Jurisdiction Policy (which however seems to be installed on your system).
For completeness: The algorithm is called PBEWITHHMACSHA512ANDAES_256 (which you have already figured out yourself).
PBEWITHHMACSHA512ANDAES_256 derives a 32 bytes key for AES-256 from password and salt using PBKDF2. HMAC/SHA512 is applied. Since not explicitly specified, the default iteration count of 1000 is used. The algorithm applies the CBC mode for encryption (which is why the IV is needed).

PS256 algorithm support for signatures in Java

According to the Java 12 security specs here the RSASSA-PSS signature scheme should be supported (actually as of Java 11).
However, if I try to use a signature with PS256 algorithm in my JWT using e.g. the nimbus jose+jwt library, then it doesn't work unless I use BouncyCastle.
val signer = RSASSASigner(signKey)
val jwsObject = JWSObject(
JWSHeader.Builder(JWSAlgorithm.PS256) // PS256 gives error; RS256 will work
.keyID(signKeyId)
.build(),
Payload(json)
jwsObject.sign(signer)
This gives an error:
java.security.NoSuchAlgorithmException: SHA256withRSAandMGF1 Signature not available
And indeed JCASupport.isSupported(JWSAlgorithm.PS256) is false
If I include BouncyCastle then it does work:
Security.addProvider(BouncyCastleProviderSingleton.getInstance())
JCASupport.isSupported(JWSAlgorithm.PS256) == true
I would have thought that BouncyCastle is not necessary anymore in Java 12 (I'm actually using Kotlin 1.3 with Java 12 and Spring Boot 2.2 and com.nimbusds 8.4 to be precise).
I would like to be independent from BouncyCastle.
What am I missing?

Python pyCrypto PKCS1 OAEP to Java Cipher

I have been given some Python code from the backend that decrypts some data. On my side, the Android app, I need to also decrypt it.
Here are some snippets of the Python code which I believe are the most relevant.
cipher = PKCS1_OAEP.new(privkey)
And this is the module that it comes from
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Cipher import PKCS1_OAEP
Looking at the documentation for PKCS1_OAEP.new
https://www.dlitz.net/software/pycrypto/api/2.6/Crypto.Cipher.PKCS1_OAEP-module.html
And then comparing with the JavaDoc for Cipher
https://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html#Cipher
I deduced that this Python algorithm can be expressed as follows using the Java Cipher class (Note the code is in Kotlin)
val cipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC")
Note that BC is the provider. I found out that BouncyCastle is popular and is included in the Android framework
So what is the error?
The backend returns me a 404 when the answer to the challenge is wrong.
When I execute the Python code (which hits the same endpoints) it works.
In terms of the POST request, I compared both and I am sending it in the correct way.
What would I like to know
Am I using the correct algorithm? I am trying to systematically cross out potential issues before moving onto another
Note that I also tried
val cipher = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC")

Public Key exchange between iOS and Java

I would like to share a public key generated on an iPhone/iPad with an Java based Server or an Android device. On the Java side (Server or Android) I would like to use java.security and libcommonCrypto (the SecKeyRef stuff) on iOS.
I've got everything working except the public key exchange between these two platforms. By using SecItemCopyMatching I can only export the public key into some format not supported by anything else then Apple. With Java I can load public keys as X509 certificate (through java.security.X509EncodedKeySpec) or as module and exponent (through java.security.RSAPublicKeySpec).
Now I need to know how to export a SecKeyRef as X509 certificate or (what I guess is the easier solution) get the module and exponent from it. And I also need the way backwards.
Here is some sample public key loaded from a SecKeyRef and encoded to BASE64:
MIGJAoGBAMYgXP6rvD/Y8F0VQE0HvxpVnnOxXYl5TDlOfW/leyrCLWGWg9Jp+Tl9dYvK/zWgNpoEfFzMVRpUk9UHcIaDWHW3g0BpS2MVC3Vs/0e2eu6S2WMGHpzqcJB51jJRbnqXQ23nVKC2YE520Po3EvFyTr8MlFJqTCJrovgc7fze4RI5AgMBAAE=
The protocol Apples libcommonCrypto is using is described in RFC3347 and is the modulus and public exponent as a ASN.1 sequence.
An RSA public key should be represented with the ASN.1 type RSAPublicKey:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
Quote from RFC3347, Ver. 2.1, A.1.1

What specific hash algorithm does MessageDigest.getInstance("SHA") return?

MessageDigest.getInstance("SHA") seems to work and gives me a MessageDigest, but I can't tell what algorithm it's giving me.
Is it SHA-1 or SHA-0 or ..?
I'm not interested in what happens on my machine. I want to know whether it will return sha0 or sha1 for all valid implementations of Java (or it's undefined).
The JCE Specification lists standard names that an implementation is expected to support. "SHA-1" is specified, as are SHA-256, SHA-384, and SHA-512. "SHA", "SHA-0" and SHA-2" are not standard names and therefore may not be supported at all. You cannot guarantee what "SHA" will return, if anything at all, because it is not in the standard.
SHA-0 is obsolete. For use with the Java JCE MessageDigest, SHA == SHA-1 for some JCE providers. By the way, SHA-1 is not considered to be secure with today's computers and technology. SHA-512 is still secure for pretty much anything. SHA-256 is ok for most things, still.
You can list the protocols available in the Java version you are using with this code. (I got it here ):
import java.security.Provider;
import java.security.Security;
public class JceLook {
public static void main(String[] args) {
System.out.println("Algorithms Supported in this JCE.");
System.out.println("====================");
// heading
System.out.println("Provider: type.algorithm -> className" + "\n aliases:" + "\n attributes:\n");
// discover providers
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
System.out.println("<><><>" + provider + "<><><>\n");
// discover services of each provider
for (Provider.Service service : provider.getServices()) {
System.out.println(service);
}
System.out.println();
}
}
}
It will show information like this for all the various algorithms available. (Note that this is actual output from the program above for some update level of Oracle/Sun Java 6 and it shows that SHA is equivalent to SHA-1 and SHA1. You can pass any of the three strings to MessageDigest and get the same result. But this depends on the Cryptography Provider (the JCE) and might not be the same.)
SUN: MessageDigest.SHA -> sun.security.provider.SHA
aliases: [SHA-1, SHA1]
attributes: {ImplementedIn=Software}
If you load additional providers (e.g. BouncyCastle) it will show those too.

Categories

Resources