protected byte[] engineSign() throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { BigInteger[] sig = signer.generateSignature(hash); return encoder.encode(sig[0], sig[1]); } catch (Exception e) { throw new SignatureException(e.toString()); } }
/** * Generate a signature for the message we've been loaded with using the key we were initialised * with. */ public byte[] generateSignature() throws CryptoException, DataLengthException { if (!forSigning) { throw new IllegalStateException("RSADigestSigner not initialised for signature generation."); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); try { byte[] data = derEncode(hash); return rsaEngine.processBlock(data, 0, data.length); } catch (IOException e) { throw new CryptoException("unable to encode signature: " + e.getMessage(), e); } }
protected boolean engineVerify(byte[] sigBytes) throws SignatureException { byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); BigInteger[] sig; try { sig = encoder.decode(sigBytes); } catch (Exception e) { throw new SignatureException("error decoding signature bytes."); } return signer.verifySignature(hash, sig[0], sig[1]); }
/** * return true if the internal state represents the signature described in the passed in array. */ public boolean verifySignature(byte[] signature) { if (forSigning) { throw new IllegalStateException("RSADigestSigner not initialised for verification"); } byte[] hash = new byte[digest.getDigestSize()]; digest.doFinal(hash, 0); byte[] sig; byte[] expected; try { sig = rsaEngine.processBlock(signature, 0, signature.length); expected = derEncode(hash); } catch (Exception e) { return false; } if (sig.length == expected.length) { return Arrays.constantTimeAreEqual(sig, expected); } else if (sig.length == expected.length - 2) // NULL left out { int sigOffset = sig.length - hash.length - 2; int expectedOffset = expected.length - hash.length - 2; expected[1] -= 2; // adjust lengths expected[3] -= 2; int nonEqual = 0; for (int i = 0; i < hash.length; i++) { nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]); } for (int i = 0; i < sigOffset; i++) { nonEqual |= (sig[i] ^ expected[i]); // check header less NULL } return nonEqual == 0; } else { return false; } }
public void performTest() throws Exception { byte[] salt = new byte[digest.getDigestSize()]; int iCount = 100; digest.doFinal(salt, 0); PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); pGen.init(PBEParametersGenerator.PKCS12PasswordToBytes(password), salt, iCount); ParametersWithIV params = (ParametersWithIV) pGen.generateDerivedParameters(keySize, ivSize); SecretKeySpec encKey = new SecretKeySpec(((KeyParameter) params.getParameters()).getKey(), baseAlgorithm); Cipher c; if (baseAlgorithm.equals("RC4")) { c = Cipher.getInstance(baseAlgorithm, "SC"); c.init(Cipher.ENCRYPT_MODE, encKey); } else { c = Cipher.getInstance(baseAlgorithm + "/CBC/PKCS7Padding", "SC"); c.init(Cipher.ENCRYPT_MODE, encKey, new IvParameterSpec(params.getIV())); } byte[] enc = c.doFinal(salt); c = Cipher.getInstance(algorithm, "SC"); PBEKeySpec keySpec = new PBEKeySpec(password, salt, iCount); SecretKeyFactory fact = SecretKeyFactory.getInstance(algorithm, "SC"); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec)); byte[] dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } // // get the parameters // AlgorithmParameters param = checkParameters(c, salt, iCount); // // try using parameters // c = Cipher.getInstance(algorithm, "SC"); keySpec = new PBEKeySpec(password); c.init(Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), param); checkParameters(c, salt, iCount); dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } // // try using PBESpec // c = Cipher.getInstance(algorithm, "SC"); keySpec = new PBEKeySpec(password); c.init( Cipher.DECRYPT_MODE, fact.generateSecret(keySpec), param.getParameterSpec(PBEParameterSpec.class)); checkParameters(c, salt, iCount); dec = c.doFinal(enc); if (!Arrays.areEqual(salt, dec)) { fail("" + algorithm + "failed encryption/decryption test"); } }