I would like to know whether there exists a public/private key specification (preferrably in Java itself, no external libs) that can do both a KeyAgreement and Signature.
Try elliptic curves:
KeyPairGenerator eckpg = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec p256 = new ECGenParameterSpec("secp256r1");
eckpg.initialize(p256);
KeyPair doubleUseKeyPair = eckpg.generateKeyPair();
KeyAgreement ecdh = KeyAgreement.getInstance("ECDH");
ecdh.init(doubleUseKeyPair.getPrivate());
// ...
Signature ecdsa = Signature.getInstance("SHA256withECDSA");
ecdsa.initSign(doubleUseKeyPair.getPrivate());
// ...
System.out.println(eckpg.getProvider());
System.out.println(ecdh.getProvider());
System.out.println(ecdsa.getProvider());
Should return:
SunEC version 1.7
SunEC version 1.7
SunEC version 1.7
This is on Java 7 from Sun/Oracle of course.
Note that using the same key (pair) two different purposes is considered bad key management by most. It may allow for attacks that uses vulnerabilities in either or a combination in both the algorithms and the protocol. Using the same key type / strength is of course fine.
Related
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).
I generate an ARCFOUR key like this :
myKeyGenerator= KeyGenerator.getInstance("ARCFOUR");
myKeyGenerator.init(1024);
myKey = myKeyGenerator.generateKey();
and then I want to store it in my KeyStorewith myKeyStore.setKeyEntry(myKeyAlias, myKey, myPassword, null); but it triggers the following error :
Key protection algorithm not found: java.security.NoSuchAlgorithmException: unrecognized algorithm name: ARCFOUR
And I don't understand why as the "ARCFOUR" algorithm is supposed to be supported by my Java implementation (retrieved through the Provider list).
And, with the same code, I don't get any error if I use the "AES" algorithm.
I use PKCS #12 for my KeyStore.
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?
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
I am using Java 1.4.2_10 and I am trying to use RSA encryption:
I am getting the NoSuchAlgorithmException for the following code:
cipher = Cipher.getInstance("RSA");
This is the error:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA
at javax.crypto.Cipher.getInstance(DashoA6275)
This works fine in 1.5 and above, however I need to use 1.4. Is there any workaround or thirdparty product that I can use to fix this?
Thanks in advance.
You can install the Bouncy Castle cryptography provider. Just grab their jars and then call Cipher.getInstance("RSA", "BC")
Java 1.4 definitely supports RSA, so the fact that this isn't working suggests that something deeper is wrong. Does this work with any other ciphers (such as "AES" or "DES")? You should check to make sure your providers are properly configured. What is the output of the following code on your system:
System.out.println("Providers: ");
java.security.Provider[] providers = java.security.Security.getProviders();
for(int x = 0; x < providers.length; x++) {
System.out.println("\t" + providers[x]);
}
System.out.println();
System.out.println("Algorithms: ");
java.util.Set algs = java.security.Security.getAlgorithms("Cipher");
java.util.Iterator i_algs = algs.iterator();
while(i_algs.hasNext()) {
System.out.println("\t" + i_algs.next());
}