RE: Issue with AES/DES RFC3211Wrap
"Eckenfels. Bernd" <[email protected]>
| Newsgroups | gmane.comp.encryption.bouncy-castle.devel |
|---|---|
| Message-ID | <ED12D06EC205E3458FC3E23CD84D4ED50212A2C4D8@DEDCEXCH01.seeburger.de> |
Just in case somebody is as confused as me why there is a single byte IV. From Reading the wrapping definition in RFC3211: it is actually not a IV but a content length. The IV used in the double wrapping is extracted by the wrap itself. Not sure why this method doesn’t Hände the length byte like it handles the check bytes bit. It would be a compatible change to use the first byte if no IVSpec was given to make this less confusing to use... Gruss Bernd -- http://www.seeburger.com ________________________________________ From: David Hook [dgh-rTAZ0PM/[email protected]] Sent: Saturday, September 15, 2018 15:54 To: MSKnete-S0/[email protected]; [email protected] Subject: Re: [dev-crypto] Issue with AES/DES RFC3211Wrap The two variations require IVs, and generate them if one is not created, so if you try the following instead: public class WrapTest { private static final Key KEY_AES128 = new SecretKeySpec(Hex.decode("c794a7735f469c59cf9d7ddd8c65201d"), "AES"); private static final Key KEY_DES = new SecretKeySpec(Hex.decode("8ccbbc15340b46c7cee6e5b6d6b6bc3e08ea38b55d3e08d9"), "DES"); private static final byte[] PLAIN = "abcdefgh".getBytes(); private static Provider prov = new BouncyCastleProvider(); public static void main(String[] args) throws Exception { // String res = wrap("AESWRAP", KEY_AES128, PLAIN); // unwrap("AESWRAP", KEY_AES128, Hex.decode(res)); // res = wrap("DESEDEWRAP", KEY_DES, PLAIN); // unwrap("DESEDEWRAP", KEY_DES, Hex.decode(res)); byte[][] res = wrap("AESRFC3211WRAP", KEY_AES128, PLAIN); unwrap("AESRFC3211WRAP", KEY_AES128, res); res = wrap("DESEDERFC3211WRAP", KEY_DES, PLAIN); unwrap("DESEDERFC3211WRAP", KEY_DES, res); } private static byte[][] wrap(String algo, Key privKey, byte[] data) throws Exception { Cipher engine = Cipher.getInstance(algo, prov); engine.init(Cipher.ENCRYPT_MODE, privKey); byte[] res = engine.doFinal(data); System.out.println(String.format("%s wrapped: %s", algo, Hex.toHexString(res))); return new byte[][] { engine.getIV(), res }; } private static String unwrap(String algo, Key privKey, byte[][] data) throws Exception { Cipher engine = Cipher.getInstance(algo, prov); engine.init(Cipher.DECRYPT_MODE, privKey, new IvParameterSpec(data[0])); String res = new String(engine.doFinal(data[1])); System.out.println(String.format("%s unwrapped: %s", algo, res)); return res; } } You should find it works. It raises an interesting point though - neither of these methods will work with data of more than 255 bytes, we should introduce a limit for these two. I'll have to add it to the list... Regards, David On 13/09/18 19:31, MSKnete-S0/[email protected]<mailto:MSKnete-S0/[email protected]> wrote: Hi, I have noticed that BC 1.60 changed the behavior of wrap ciphers in a way so that they can be also used in encrypt mode for wrapping data. This apparently works fine with AESWRAP and DESEDEWRAP. However when using AESRFC3211WRAP and DESEDERFC3211WRAP the wrapped data can't be unwrapped due to a javax.crypto.BadPaddingException. Please see the following class to demonstrate the issue: import java.security.Key; import java.security.Provider; import java.util.Locale; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; public class WrapTest { private static final Key KEY_AES128 = new SecretKeySpec(Hex.decode("c794a7735f469c59cf9d7ddd8c65201d"), "AES"); private static final Key KEY_DES = new SecretKeySpec(Hex.decode("8ccbbc15340b46c7cee6e5b6d6b6bc3e08ea38b55d3e08d9"), "DES"); private static final byte[] PLAIN = "abcdefgh".getBytes(); private static Provider prov = new BouncyCastleProvider(); public static void main(String[] args) throws Exception { String res = wrap("AESWRAP", KEY_AES128, PLAIN); unwrap("AESWRAP", KEY_AES128, Hex.decode(res)); res = wrap("DESEDEWRAP", KEY_DES, PLAIN); unwrap("DESEDEWRAP", KEY_DES, Hex.decode(res)); res = wrap("AESRFC3211WRAP", KEY_AES128, PLAIN); unwrap("AESRFC3211WRAP", KEY_AES128, Hex.decode(res)); res = wrap("DESEDERFC3211WRAP", KEY_DES, PLAIN); unwrap("DESEDERFC3211WRAP", KEY_DES, Hex.decode(res)); } private static String wrap(String algo, Key privKey, byte[] data) throws Exception { Cipher engine = Cipher.getInstance(algo, prov); engine.init(Cipher.ENCRYPT_MODE, privKey); String res = Hex.toHexString(engine.doFinal(data)).toUpperCase(Locale.ROOT); System.out.println(String.format("%s wrapped: %s", algo, res)); return res; } private static String unwrap(String algo, Key privKey, byte[] data) throws Exception { Cipher engine = Cipher.getInstance(algo, prov); engine.init(Cipher.DECRYPT_MODE, privKey); String res = new String(engine.doFinal(data)); System.out.println(String.format("%s unwrapped: %s", algo, res)); return res; } } Is this an issue or have I just used the API wrong? Kind Regards, Michael Schäfer SEEBURGER AG Vorstand/SEEBURGER Executive Board: Sitz der Gesellschaft/Registered Office: Axel Haas, Michael Kleeberg, Friedemann Heinz, Dr. Martin Kuntz, Matthias Feßenbecker Edisonstr. 1 D-75015 Bretten Vorsitzende des Aufsichtsrats/Chairperson of the SEEBURGER Supervisory Board: Tel.: 07252 / 96 - 0 Prof. Dr. Simone Zeuchner Fax: 07252 / 96 - 2222 Internet: http://www.seeburger.de Registergericht/Commercial Register: e-mail: [email protected] HRB 240708 Mannheim Dieses E-Mail ist nur für den Empfänger bestimmt, an den es gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder Meinungsäußerung ist die des Autors und stellt nicht notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung, Abschrift oder jeglicher Druck dieser E-Mail ist strengstens untersagt. Weder die SEEBURGER AG noch der Absender (Eckenfels. Bernd) übernehmen die Haftung für Viren; es obliegt Ihrer Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen. This email is intended only for the recipient(s) to whom it is addressed. This email may contain confidential material that may be protected by professional secrecy. Any fact or opinion contained, or expression of the material herein, does not necessarily reflect that of SEEBURGER AG. If you are not the addressee or if you have received this email in error, any use, publication or distribution including forwarding, copying or printing is strictly prohibited. Neither SEEBURGER AG, nor the sender (Eckenfels. Bernd) accept liability for viruses; it is your responsibility to check this email and its attachments for viruses.