001: package org.bouncycastle.crypto.test;
002:
003: import org.bouncycastle.crypto.AsymmetricBlockCipher;
004: import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
005: import org.bouncycastle.crypto.InvalidCipherTextException;
006: import org.bouncycastle.crypto.encodings.OAEPEncoding;
007: import org.bouncycastle.crypto.encodings.PKCS1Encoding;
008: import org.bouncycastle.crypto.engines.RSABlindedEngine;
009: import org.bouncycastle.crypto.engines.RSAEngine;
010: import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
011: import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
012: import org.bouncycastle.crypto.params.RSAKeyParameters;
013: import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
014: import org.bouncycastle.util.encoders.Hex;
015: import org.bouncycastle.util.test.SimpleTest;
016:
017: import java.math.BigInteger;
018: import java.security.SecureRandom;
019:
020: public class RSABlindedTest extends SimpleTest {
021: static BigInteger mod = new BigInteger(
022: "b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5",
023: 16);
024: static BigInteger pubExp = new BigInteger("11", 16);
025: static BigInteger privExp = new BigInteger(
026: "92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619",
027: 16);
028: static BigInteger p = new BigInteger(
029: "f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03",
030: 16);
031: static BigInteger q = new BigInteger(
032: "b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947",
033: 16);
034: static BigInteger pExp = new BigInteger(
035: "1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5",
036: 16);
037: static BigInteger qExp = new BigInteger(
038: "6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded",
039: 16);
040: static BigInteger crtCoef = new BigInteger(
041: "dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339",
042: 16);
043:
044: static String input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
045:
046: //
047: // to check that we handling byte extension by big number correctly.
048: //
049: static String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
050:
051: static byte[] oversizedSig = Hex
052: .decode("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e");
053: static byte[] dudBlock = Hex
054: .decode("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e");
055: static byte[] truncatedDataBlock = Hex
056: .decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e");
057: static byte[] incorrectPadding = Hex
058: .decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e");
059: static byte[] missingDataBlock = Hex
060: .decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
061:
062: public String getName() {
063: return "RSABlinded";
064: }
065:
066: private void testStrictPKCS1Length(RSAKeyParameters pubParameters,
067: RSAKeyParameters privParameters) {
068: AsymmetricBlockCipher eng = new RSABlindedEngine();
069:
070: eng.init(true, privParameters);
071:
072: byte[] data = null;
073:
074: try {
075: data = eng.processBlock(oversizedSig, 0,
076: oversizedSig.length);
077: } catch (Exception e) {
078: fail("RSA: failed - exception " + e.toString(), e);
079: }
080:
081: eng = new PKCS1Encoding(eng);
082:
083: eng.init(false, pubParameters);
084:
085: try {
086: data = eng.processBlock(data, 0, data.length);
087:
088: fail("oversized signature block not recognised");
089: } catch (InvalidCipherTextException e) {
090: if (!e.getMessage().equals("block incorrect size")) {
091: fail("RSA: failed - exception " + e.toString(), e);
092: }
093: }
094:
095: //System.setProperty(PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, "false");
096:
097: System.getProperties().put(
098: PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY, "false");
099: eng = new PKCS1Encoding(new RSABlindedEngine());
100:
101: eng.init(false, pubParameters);
102:
103: try {
104: data = eng.processBlock(data, 0, data.length);
105: } catch (InvalidCipherTextException e) {
106: fail("RSA: failed - exception " + e.toString(), e);
107: }
108:
109: System.getProperties().remove(
110: PKCS1Encoding.STRICT_LENGTH_ENABLED_PROPERTY);
111: }
112:
113: private void testTruncatedPKCS1Block(
114: RSAKeyParameters pubParameters,
115: RSAKeyParameters privParameters) {
116: checkForPKCS1Exception(pubParameters, privParameters,
117: truncatedDataBlock, "block truncated");
118: }
119:
120: private void testDudPKCS1Block(RSAKeyParameters pubParameters,
121: RSAKeyParameters privParameters) {
122: checkForPKCS1Exception(pubParameters, privParameters, dudBlock,
123: "unknown block type");
124: }
125:
126: private void testWrongPaddingPKCS1Block(
127: RSAKeyParameters pubParameters,
128: RSAKeyParameters privParameters) {
129: checkForPKCS1Exception(pubParameters, privParameters,
130: incorrectPadding, "block padding incorrect");
131: }
132:
133: private void testMissingDataPKCS1Block(
134: RSAKeyParameters pubParameters,
135: RSAKeyParameters privParameters) {
136: checkForPKCS1Exception(pubParameters, privParameters,
137: missingDataBlock, "no data in block");
138: }
139:
140: private void checkForPKCS1Exception(RSAKeyParameters pubParameters,
141: RSAKeyParameters privParameters, byte[] inputData,
142: String expectedMessage) {
143: AsymmetricBlockCipher eng = new RSABlindedEngine();
144:
145: eng.init(true, privParameters);
146:
147: byte[] data = null;
148:
149: try {
150: data = eng.processBlock(inputData, 0, inputData.length);
151: } catch (Exception e) {
152: fail("RSA: failed - exception " + e.toString(), e);
153: }
154:
155: eng = new PKCS1Encoding(eng);
156:
157: eng.init(false, pubParameters);
158:
159: try {
160: data = eng.processBlock(data, 0, data.length);
161:
162: fail("missing data block not recognised");
163: } catch (InvalidCipherTextException e) {
164: if (!e.getMessage().equals(expectedMessage)) {
165: fail("RSA: failed - exception " + e.toString(), e);
166: }
167: }
168: }
169:
170: private void testOAEP(RSAKeyParameters pubParameters,
171: RSAKeyParameters privParameters) {
172: //
173: // OAEP - public encrypt, private decrypt
174: //
175: AsymmetricBlockCipher eng = new OAEPEncoding(
176: new RSABlindedEngine());
177: byte[] data = Hex.decode(input);
178:
179: eng.init(true, pubParameters);
180:
181: try {
182: data = eng.processBlock(data, 0, data.length);
183: } catch (Exception e) {
184: fail("failed - exception " + e.toString(), e);
185: }
186:
187: eng.init(false, privParameters);
188:
189: try {
190: data = eng.processBlock(data, 0, data.length);
191: } catch (Exception e) {
192: fail("failed - exception " + e.toString(), e);
193: }
194:
195: if (!input.equals(new String(Hex.encode(data)))) {
196: fail("failed OAEP Test");
197: }
198: }
199:
200: public void performTest() {
201: RSAKeyParameters pubParameters = new RSAKeyParameters(false,
202: mod, pubExp);
203: RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(
204: mod, pubExp, privExp, p, q, pExp, qExp, crtCoef);
205: byte[] data = Hex.decode(edgeInput);
206:
207: //
208: // RAW
209: //
210: AsymmetricBlockCipher eng = new RSABlindedEngine();
211:
212: eng.init(true, pubParameters);
213:
214: try {
215: data = eng.processBlock(data, 0, data.length);
216: } catch (Exception e) {
217: fail("RSA: failed - exception " + e.toString(), e);
218: }
219:
220: eng.init(false, privParameters);
221:
222: try {
223: data = eng.processBlock(data, 0, data.length);
224: } catch (Exception e) {
225: fail("failed - exception " + e.toString(), e);
226: }
227:
228: if (!edgeInput.equals(new String(Hex.encode(data)))) {
229: fail("failed RAW edge Test");
230: }
231:
232: data = Hex.decode(input);
233:
234: eng.init(true, pubParameters);
235:
236: try {
237: data = eng.processBlock(data, 0, data.length);
238: } catch (Exception e) {
239: fail("failed - exception " + e.toString(), e);
240: }
241:
242: eng.init(false, privParameters);
243:
244: try {
245: data = eng.processBlock(data, 0, data.length);
246: } catch (Exception e) {
247: fail("failed - exception " + e.toString(), e);
248: }
249:
250: if (!input.equals(new String(Hex.encode(data)))) {
251: fail("failed RAW Test");
252: }
253:
254: //
255: // PKCS1 - public encrypt, private decrypt
256: //
257: eng = new PKCS1Encoding(eng);
258:
259: eng.init(true, pubParameters);
260:
261: if (eng.getOutputBlockSize() != ((PKCS1Encoding) eng)
262: .getUnderlyingCipher().getOutputBlockSize()) {
263: fail("PKCS1 output block size incorrect");
264: }
265:
266: try {
267: data = eng.processBlock(data, 0, data.length);
268: } catch (Exception e) {
269: fail("failed - exception " + e.toString(), e);
270: }
271:
272: eng.init(false, privParameters);
273:
274: try {
275: data = eng.processBlock(data, 0, data.length);
276: } catch (Exception e) {
277: fail("failed - exception " + e.toString(), e);
278: }
279:
280: if (!input.equals(new String(Hex.encode(data)))) {
281: fail("failed PKCS1 public/private Test");
282: }
283:
284: //
285: // PKCS1 - private encrypt, public decrypt
286: //
287: eng = new PKCS1Encoding(((PKCS1Encoding) eng)
288: .getUnderlyingCipher());
289:
290: eng.init(true, privParameters);
291:
292: try {
293: data = eng.processBlock(data, 0, data.length);
294: } catch (Exception e) {
295: fail("failed - exception " + e.toString(), e);
296: }
297:
298: eng.init(false, pubParameters);
299:
300: try {
301: data = eng.processBlock(data, 0, data.length);
302: } catch (Exception e) {
303: fail("failed - exception " + e.toString(), e);
304: }
305:
306: if (!input.equals(new String(Hex.encode(data)))) {
307: fail("failed PKCS1 private/public Test");
308: }
309:
310: //
311: // key generation test
312: //
313: RSAKeyPairGenerator pGen = new RSAKeyPairGenerator();
314: RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters(
315: BigInteger.valueOf(0x11), new SecureRandom(), 768, 25);
316:
317: pGen.init(genParam);
318:
319: AsymmetricCipherKeyPair pair = pGen.generateKeyPair();
320:
321: eng = new RSABlindedEngine();
322:
323: if (((RSAKeyParameters) pair.getPublic()).getModulus()
324: .bitLength() < 768) {
325: fail("failed key generation (768) length test");
326: }
327:
328: eng.init(true, pair.getPublic());
329:
330: try {
331: data = eng.processBlock(data, 0, data.length);
332: } catch (Exception e) {
333: fail("failed - exception " + e.toString(), e);
334: }
335:
336: eng.init(false, pair.getPrivate());
337:
338: try {
339: data = eng.processBlock(data, 0, data.length);
340: } catch (Exception e) {
341: fail("failed - exception " + e.toString(), e);
342: }
343:
344: if (!input.equals(new String(Hex.encode(data)))) {
345: fail("failed key generation (768) Test");
346: }
347:
348: genParam = new RSAKeyGenerationParameters(BigInteger
349: .valueOf(0x11), new SecureRandom(), 1024, 25);
350:
351: pGen.init(genParam);
352: pair = pGen.generateKeyPair();
353:
354: eng.init(true, pair.getPublic());
355:
356: if (((RSAKeyParameters) pair.getPublic()).getModulus()
357: .bitLength() < 1024) {
358: fail("failed key generation (1024) length test");
359: }
360:
361: try {
362: data = eng.processBlock(data, 0, data.length);
363: } catch (Exception e) {
364: fail("failed - exception " + e.toString(), e);
365: }
366:
367: eng.init(false, pair.getPrivate());
368:
369: try {
370: data = eng.processBlock(data, 0, data.length);
371: } catch (Exception e) {
372: fail("failed - exception " + e.toString(), e);
373: }
374:
375: if (!input.equals(new String(Hex.encode(data)))) {
376: fail("failed key generation (1024) test");
377: }
378:
379: testOAEP(pubParameters, privParameters);
380: testStrictPKCS1Length(pubParameters, privParameters);
381: testDudPKCS1Block(pubParameters, privParameters);
382: testMissingDataPKCS1Block(pubParameters, privParameters);
383: testTruncatedPKCS1Block(pubParameters, privParameters);
384: testWrongPaddingPKCS1Block(pubParameters, privParameters);
385:
386: try {
387: new RSABlindedEngine().processBlock(new byte[] { 1 }, 0, 1);
388: fail("failed initialisation check");
389: } catch (IllegalStateException e) {
390: // expected
391: }
392: }
393:
394: public static void main(String[] args) {
395: runTest(new RSABlindedTest());
396: }
397: }
|