-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
6u24
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
The implementation of SunJCE's Cipher "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" is not compatible with other implementations (BouncyCastle/IAIK/PKCS11)
When setting AlgorithmParameters (with OAEPParameterSpec) an exception is thrown (javax.crypto.BadPaddingException)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Encrypt data with SunJCE Provider and "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"
Try to decrypt the data e.g. with BouncyCastleProvider
Initialize the Cipher explicit with AlgorithmParameters (OAEPParameterSpec)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Data encrypted with SunJCE provider and "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" should be able to decrypt with other implementations
No exception when setting AlgorithmParameters
ACTUAL -
BouncyCastle cannot decrypt the data.
javax.crypto.BadPaddingException when setting AlgorithmParameters
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.crypto.BadPaddingException: data hash wrong
at org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.secunet.BugReport.testSHA256_1(BugReport.java:72)
at com.secunet.BugReport.main(BugReport.java:31)
javax.crypto.BadPaddingException: java.security.DigestException: Length must be at least 32 for SHA-256digests
at sun.security.rsa.RSAPadding.mgf1(RSAPadding.java:452)
at sun.security.rsa.RSAPadding.padOAEP(RSAPadding.java:377)
at sun.security.rsa.RSAPadding.pad(RSAPadding.java:229)
at sun.security.rsa.RSAPadding.pad(RSAPadding.java:211)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.secunet.BugReport.testSHA256_2(BugReport.java:93)
at com.secunet.BugReport.main(BugReport.java:33)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.secunet;
import java.security.AlgorithmParameters;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
//Note: you must have http://www.bouncycastle.org/download/bcprov-jdk16-146.jar in classpath
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class BugReport {
public static final String data = "1234567890";
public static void main(String [] args) {
try {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
testSHA1(kp);
System.out.println();
testSHA256_1(kp);
System.out.println();
testSHA256_2(kp);
}
catch (Throwable e) {
e.printStackTrace();
}
finally {
System.out.println("END");
}
}
public static void testSHA1(KeyPair kp) {
try {
Cipher ce = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "SunJCE");
ce.init(Cipher.ENCRYPT_MODE, kp.getPublic());
byte [] encryptedData = ce.doFinal(data.getBytes());
Cipher cd = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "BC");
cd.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte [] decryptedData = cd.doFinal(encryptedData);
if (!Arrays.equals(data.getBytes(), decryptedData))
throw new RuntimeException("Decrypt Faild, data not equal");
System.out.println("OK: SHA-1 test");
}
catch (Exception e) {
e.printStackTrace(System.out);
System.out.println("ERROR: SHA-1 test");
}
}
public static void testSHA256_1(KeyPair kp){
try{
Cipher ce = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "SunJCE");
ce.init(Cipher.ENCRYPT_MODE, kp.getPublic());
byte [] encryptedData = ce.doFinal(data.getBytes());
Cipher cd = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "BC");
cd.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte [] decryptedData = cd.doFinal(encryptedData);
if (!Arrays.equals(data.getBytes(), decryptedData))
throw new RuntimeException ("Decrypt Faild, data not equal");
System.out.println("OK: SHA-256 test");
}catch(Exception e){
e.printStackTrace(System.out);
System.out.println("ERROR: SHA-256 test");
}
}
public static void testSHA256_2(KeyPair kp){
try{
AlgorithmParameters algp = AlgorithmParameters.getInstance("OAEP", "SunJCE");
AlgorithmParameterSpec paramSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT);
algp.init(paramSpec);
Cipher ce = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "SunJCE");
ce.init(Cipher.ENCRYPT_MODE, kp.getPublic(), algp);
byte [] encryptedData = ce.doFinal(data.getBytes());
Cipher cd = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "BC");
cd.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte [] decryptedData = cd.doFinal(encryptedData);
if (!Arrays.equals(data.getBytes(), decryptedData))
throw new RuntimeException ("Decrypt Faild, data not equal");
System.out.println("OK: SHA-256 with parameter test");
}catch(Exception e){
e.printStackTrace(System.out);
System.out.println("ERROR: SHA-256 with parameter test");
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do the OAEP padding (PKCS#1 V2.1) manually and use cipher "RSA/ECB/NOPADDING"
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
The implementation of SunJCE's Cipher "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" is not compatible with other implementations (BouncyCastle/IAIK/PKCS11)
When setting AlgorithmParameters (with OAEPParameterSpec) an exception is thrown (javax.crypto.BadPaddingException)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Encrypt data with SunJCE Provider and "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"
Try to decrypt the data e.g. with BouncyCastleProvider
Initialize the Cipher explicit with AlgorithmParameters (OAEPParameterSpec)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Data encrypted with SunJCE provider and "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" should be able to decrypt with other implementations
No exception when setting AlgorithmParameters
ACTUAL -
BouncyCastle cannot decrypt the data.
javax.crypto.BadPaddingException when setting AlgorithmParameters
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.crypto.BadPaddingException: data hash wrong
at org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.secunet.BugReport.testSHA256_1(BugReport.java:72)
at com.secunet.BugReport.main(BugReport.java:31)
javax.crypto.BadPaddingException: java.security.DigestException: Length must be at least 32 for SHA-256digests
at sun.security.rsa.RSAPadding.mgf1(RSAPadding.java:452)
at sun.security.rsa.RSAPadding.padOAEP(RSAPadding.java:377)
at sun.security.rsa.RSAPadding.pad(RSAPadding.java:229)
at sun.security.rsa.RSAPadding.pad(RSAPadding.java:211)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.secunet.BugReport.testSHA256_2(BugReport.java:93)
at com.secunet.BugReport.main(BugReport.java:33)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.secunet;
import java.security.AlgorithmParameters;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
//Note: you must have http://www.bouncycastle.org/download/bcprov-jdk16-146.jar in classpath
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class BugReport {
public static final String data = "1234567890";
public static void main(String [] args) {
try {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
testSHA1(kp);
System.out.println();
testSHA256_1(kp);
System.out.println();
testSHA256_2(kp);
}
catch (Throwable e) {
e.printStackTrace();
}
finally {
System.out.println("END");
}
}
public static void testSHA1(KeyPair kp) {
try {
Cipher ce = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "SunJCE");
ce.init(Cipher.ENCRYPT_MODE, kp.getPublic());
byte [] encryptedData = ce.doFinal(data.getBytes());
Cipher cd = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "BC");
cd.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte [] decryptedData = cd.doFinal(encryptedData);
if (!Arrays.equals(data.getBytes(), decryptedData))
throw new RuntimeException("Decrypt Faild, data not equal");
System.out.println("OK: SHA-1 test");
}
catch (Exception e) {
e.printStackTrace(System.out);
System.out.println("ERROR: SHA-1 test");
}
}
public static void testSHA256_1(KeyPair kp){
try{
Cipher ce = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "SunJCE");
ce.init(Cipher.ENCRYPT_MODE, kp.getPublic());
byte [] encryptedData = ce.doFinal(data.getBytes());
Cipher cd = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "BC");
cd.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte [] decryptedData = cd.doFinal(encryptedData);
if (!Arrays.equals(data.getBytes(), decryptedData))
throw new RuntimeException ("Decrypt Faild, data not equal");
System.out.println("OK: SHA-256 test");
}catch(Exception e){
e.printStackTrace(System.out);
System.out.println("ERROR: SHA-256 test");
}
}
public static void testSHA256_2(KeyPair kp){
try{
AlgorithmParameters algp = AlgorithmParameters.getInstance("OAEP", "SunJCE");
AlgorithmParameterSpec paramSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT);
algp.init(paramSpec);
Cipher ce = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "SunJCE");
ce.init(Cipher.ENCRYPT_MODE, kp.getPublic(), algp);
byte [] encryptedData = ce.doFinal(data.getBytes());
Cipher cd = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING", "BC");
cd.init(Cipher.DECRYPT_MODE, kp.getPrivate());
byte [] decryptedData = cd.doFinal(encryptedData);
if (!Arrays.equals(data.getBytes(), decryptedData))
throw new RuntimeException ("Decrypt Faild, data not equal");
System.out.println("OK: SHA-256 with parameter test");
}catch(Exception e){
e.printStackTrace(System.out);
System.out.println("ERROR: SHA-256 with parameter test");
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Do the OAEP padding (PKCS#1 V2.1) manually and use cipher "RSA/ECB/NOPADDING"