/** * Hidden (package-private) initializer, for internal/unittest usage. */ void init(byte[] e, byte[] p, byte[] q, HashType oaepHashType, HashType mgf1HashType, SecureRandom rng) { final RSAKeyPair keyPair = RSAKeyPair.fromExponents(e, p, q); final RSAPrivateCrtKeyParameters privParameters = new RSAPrivateCrtKeyParameters( BigIntegers.fromUnsignedByteArray(keyPair.n), BigIntegers.fromUnsignedByteArray(keyPair.e), BigIntegers.fromUnsignedByteArray(keyPair.d), BigIntegers.fromUnsignedByteArray(keyPair.p), BigIntegers.fromUnsignedByteArray(keyPair.q), BigIntegers.fromUnsignedByteArray(keyPair.dP), BigIntegers.fromUnsignedByteArray(keyPair.dQ), BigIntegers.fromUnsignedByteArray(keyPair.qInv)); final AsymmetricBlockCipher decryptor = makeDecryptor(mgf1HashType); // Private key goes together with its public key. final RSAOAEPPublicKey publicKey = new RSAOAEPPublicKey(); publicKey.init(keyPair.n, keyPair.e, oaepHashType, mgf1HashType, rng); state = new RSAOAEPPrivateKey.State(decryptor, privParameters, publicKey, oaepHashType, mgf1HashType, rng); resetDecryptor(); }
/** * Hidden (package-private) initializer, for internal/unittest usage. */ void init(byte[] n, byte[] e, HashType oaepHashType, HashType mgf1HashType, SecureRandom rng) { final RSAKeyParameters pubParameters = new RSAKeyParameters( false, BigIntegers.fromUnsignedByteArray(n), BigIntegers.fromUnsignedByteArray(e)); state = new State(makeEncryptor(mgf1HashType), pubParameters, oaepHashType, mgf1HashType, rng); resetEncryptor(); }
/** * Generate from the exponents. */ public static RSAKeyPair fromExponents(byte[] e, byte[] p, byte[] q) { final BigInteger eInt = BigIntegers.fromUnsignedByteArray(e), pInt = BigIntegers.fromUnsignedByteArray(p), qInt = BigIntegers.fromUnsignedByteArray(q), nInt = pInt.multiply(qInt), mInt = pInt.subtract(BigInteger.ONE).multiply(qInt.subtract(BigInteger.ONE)), dInt = eInt.modInverse(mInt), dPInt = dInt.remainder(pInt.subtract(BigInteger.ONE)), dQInt = dInt.remainder(qInt.subtract(BigInteger.ONE)), qInvInt = qInt.modInverse(pInt); final byte[] n = BigIntegers.asUnsignedByteArray(nInt), d = BigIntegers.asUnsignedByteArray(dInt), dP = BigIntegers.asUnsignedByteArray(dPInt), dQ = BigIntegers.asUnsignedByteArray(dQInt), qInv = BigIntegers.asUnsignedByteArray(qInvInt); return new RSAKeyPair(n, e, d, p, q, dP, dQ, qInv); } }
BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength); BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength); BigInteger Y = BigIntegers.fromUnsignedByteArray(encoded, 1 + expectedLength, expectedLength); BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength); BigInteger Y = BigIntegers.fromUnsignedByteArray(encoded, 1 + expectedLength, expectedLength);
Log.v(TAG, "Provsionee Y: " + MeshParserUtils.bytesToHex(provisioneeY, false)); final BigInteger x = BigIntegers.fromUnsignedByteArray(xy, 0, 32); final BigInteger y = BigIntegers.fromUnsignedByteArray(xy, 32, 32);
/** * Generate a new key pair, with all options specified. * * @param bitStrength bit strength of the key, e.g. 2048 * @param e RSA public exponent * @param certainty RSA key generation certainty * @param mgf1HashType The type of the hash(digest) function used for OAEP MGF1 hash generation. */ public void generate(int bitStrength, byte[] e, int certainty, HashType oaepHashType, HashType mgf1HashType) { final RSAKeyPairGenerator keyGen = new RSAKeyPairGenerator(); keyGen.init(new RSAKeyGenerationParameters( BigIntegers.fromUnsignedByteArray(e), new SecureRandom(), bitStrength, certainty)); final AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); final RSAPrivateCrtKeyParameters privateKey = (RSAPrivateCrtKeyParameters) keyPair.getPrivate(); if (mgf1HashType == null) { mgf1HashType = DEFAULT_MGF1_HASH; } // Don't worry we are passing thread-unsafe hash and mgf1Hash Digest instances: // init() will clone them anyway. init(e, BigIntegers.asUnsignedByteArray(privateKey.getP()), BigIntegers.asUnsignedByteArray(privateKey.getQ()), oaepHashType, mgf1HashType, new SecureRandom()); }
/** * Test {@link RSAOAEPPublicKey#checkSignature} with non-usual salt. */ @Test public void checkSignatureWithCustomSalt() throws Exception { byte[] e = Hex.decode("010001"); byte[] p = Hex.decode("cd28ffefa9150bd3a8e9b0410e411920ed853c797e41038e9325125bb5fec3258eaba816fcc71ba86a2489da965d825fc0a3dabb31f5190ee80c2a0e7a73c9122e099b8a00c0a819e779e0b2cb07ca71acfb6209d8d607eb58ed314529eced00de559f3201bd3346a64c119cb92290d486a53f77087a232ea3fdb37946ad8e6dc6498da8defc63c30238d2622bcd58f3186e6e3d20f9b2872fd32127236d6eb4b57fa297c9814b2a3881fe2a538ed8d459f7f04faddbffc143f6e02b37d6b648b3c9df51aa7f2425e470ffe105d583c50d1a2da2c89f913a3af90a71ae2fafaff900e09ed4425f2a1c752b7e4f0c54b15640ae9adfd1c9cfcd75717d45a71381"); byte[] q = Hex.decode("fef327944862e322f6dae4649354af28bd32d938b0aeb8a25bf9186e6e3d20f9b2872fd32127236d6eb4b57fa26c2664af885a9e0830cf0a4a4b61d4e3650b3e0dd4507f21f2945479993d6a7d67d960017a42da25e470ff22fd6304e803bcb36cf1ec791ba1e4cc0a88863ca6d8e178a5cba71bb09504e2decfded5a81bbb01e43c02ea8ae795485864f91e3591f864c43da77a5993d213bab24cd9f95a2648f4cba8a56423e7b999b72fa4824f4bd95c5d61f4430e230b71473ef0cc530924654d0cb8c71f4ddba5007ceb93b80a466ec54665f9fe7b9c3804d7ebd13f0768af2d28cefa7240544cd2eb1815fbd40df864dcc4ad8bf4ac05383c56960b17c7"); byte[] nExpected = Hex.decode("cc518b92cef4a1baf1fe3fd3a4419bb5a0a5fe381c7d4b365dd672343a911236474a2fdff759dac21b40af42e83ec8ff30e403ed339faca0ab3a15f72a22dc822184a4949179590cbd53098d443fed61209a47223c4c6212e1b0085824d4ffd7f2d4927533f89a98132d070a61b062873c22b7ae65411a1ea6a9d33d30c5bbe63b19e05fe7589ac50ba5b704ee6fe9338d09dd7e9efd071534646101d058e676c9b650381ff5a0cdb2f11c3167378a25493957cb3ac71770a43cd77bc605b41f11c437560c0a0271154c4782f9c6a731477260e7334a380b81b197c1af53608d9ea451b136afdf7ada9ebba46db0a92464c7283b48a2eb332a89cc70ec02b8c66adc1e2344365db7f7bae30fe793e36eeacc93663969aca23a863556b2b9c4ff690f9f87994fa246c514bec71c91d0df26436934da51a6d484667d5e8f46f3599a8a5f52287dfd019e919ef4650406a44657f59342426ad61d33668b217ffe5f333c1858ce4cbbdcbbb71d486bca83f4eefed82088ea13e8b82288b639446831f61f298e96ebf5281056ed51d5f3e8e25c341386c699f4954a3f33a82efaf88e7d791e311bfbbcc947865349af32ddad1a5addafb10ff7401549a1c53bb7777533e269ec94e73d6f5927662c403a05b7b0541b3af816e91da94bbab8b095fedbb003253deffcbafb4190057f523564646d3f16d9e43a3b8be29a2694942bc047"); RSAOAEPPrivateKey privateKey = new RSAOAEPPrivateKey(e, p, q, HashType.SHA1, HashType.SHA1, new SecureRandom()); RSAOAEPPublicKey publicKey = (RSAOAEPPublicKey) privateKey.getPublicKey(); assertEquals(publicKey.state.keyParameters.getModulus(), BigIntegers.fromUnsignedByteArray(nExpected)); byte[] message = Hex.decode("4655424152206d65616e73204675636b6564205570204265796f756420416c6c205265636f676e6974696f6e"); // Signature using SHA-1 byte[] signatureExpected = Hex.decode("78def239f5d4809c0557d11407c4825e6afb261873ab9f5d3e3fc22d4faa6c358b81c96d486ae2dbc8ad5ccecec6f49a0d5207579444b85ee4ec9a2d06a737a87717083282c4cf4af1ecc14a4fdfbdaa0d53e139fc77226bc4a01fe55bbc8a29403969911c3599508aaa8701f064b95e7e64b349e320724d6c9e2af5a8556d253bed772fb659bbee0e0a6dfe205d58f71f049b023d9ce8b278eaf3141cec06aab46e78cde55d3c403784819c34741deb681bdc2cee01c41e549f17aeb59ca80b8f045de1cf4ff983599e422bce2e68903d717291d897cf39961577e5fc9af9619379790628dbf369fee707a6a4daa3211ff840b46807351204acb60acc528099f851b8a76b4eaae5f84715ecc971c296f9cf3e058badc544a01e7d1dbef1c353d8704c6cffea9398e7ee6fda895d0dabc8ac18ed88c9497664c867e93e56fbebd4436eb3efa755f8fac3fa627e795be43d92d904fe0a9af989a6c504b1e11617d45b75cb5166795e58e69dfed4bf800f8088b0b48e12600c7f460bdaf34a1999d47ce3f5e11343d1e2b1797fc744aab9fcc938d08f70f91dd30c937e0515f8eb03e1a034044c33fbfbed83df5a1b7145ef0fcbb0f41f909793bd23bd964af1c5a53f72ef7b5920cd77d25cc2d9a7a38cbd86cbb3314222ae1ea3432f1370aefb1ea5780630b5f41c0cd408391537b05e242d0c7e0e6dadfd1de2c6c9500298c3"); int expectedSaltLength = 490; // If we don't specify the salt size, it should be maximum possible; in our specific case, it's 490. assertTrue(publicKey.checkSignature(message, signatureExpected, HashType.SHA1, expectedSaltLength)); assertTrue(publicKey.checkSignature(message, signatureExpected, HashType.SHA1)); // It should NOT be 0 by default! assertFalse(publicKey.checkSignature(message, signatureExpected, HashType.SHA1, 0)); // Nevertheless, a signature made with the default parameters // should be checkable with the default parameters. assertTrue(publicKey.checkSignature(message, privateKey.sign(message, HashType.SHA1), HashType.SHA1)); }