/** * Validates the payload received from the other participant during round 1. * <p/> * <p/> * Must be called prior to {@link #createRound2PayloadToSend()}. * <p/> * <p/> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called multiple times. */ public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); } this.partnerParticipantId = round1PayloadReceived.getParticipantId(); this.gx3 = round1PayloadReceived.getGx1(); this.gx4 = round1PayloadReceived.getGx2(); BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); JPAKEUtil.validateGx4(gx4); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_1_VALIDATED; }
/** * Validates the payload received from the other participant during round 2. * <p/> * <p/> * Note that this DOES NOT detect a non-common password. * The only indication of a non-common password is through derivation * of different keys (which can be detected explicitly by executing round 3 and round 4) * <p/> * <p/> * Must be called prior to {@link #calculateKeyingMaterial()}. * <p/> * <p/> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public void validateRound2PayloadReceived(JPAKERound2Payload round2PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_2_VALIDATED) { throw new IllegalStateException("Validation already attempted for round2 payload for" + participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to validating Round2 payload for " + this.participantId); } BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); this.b = round2PayloadReceived.getA(); BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateGa(gB); JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_2_VALIDATED; }
/** * 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); } }
public byte[] generateRawSignature(SignatureAndHashAlgorithm algorithm, AsymmetricKeyParameter privateKey, byte[] hash) throws CryptoException { Signer signer = makeSigner(algorithm, true, true, new ParametersWithRandom(privateKey, this.context.getSecureRandom())); if (algorithm == null) { // Note: Only use the SHA1 part of the (MD5/SHA1) hash signer.update(hash, 16, 20); } else { signer.update(hash, 0, hash.length); } return signer.generateSignature(); }
public boolean verifyRawSignature(SignatureAndHashAlgorithm algorithm, byte[] sigBytes, AsymmetricKeyParameter publicKey, byte[] hash) throws CryptoException { Signer signer = makeSigner(algorithm, true, false, publicKey); if (algorithm == null) { // Note: Only use the SHA1 part of the (MD5/SHA1) hash signer.update(hash, 16, 20); } else { signer.update(hash, 0, hash.length); } return signer.verifySignature(sigBytes); }
public void processClientKeyExchange(InputStream input) throws IOException { /* * RFC 5054 2.5.4: The server MUST abort the handshake with an "illegal_parameter" alert if * A % N = 0. */ try { this.srpPeerCredentials = SRP6Util.validatePublicValue(srpGroup.getN(), TlsSRPUtils.readSRPParameter(input)); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); } context.getSecurityParameters().srpIdentity = Arrays.clone(identity); }
public byte[] generatePremasterSecret() throws IOException { try { BigInteger S = srpServer != null ? srpServer.calculateSecret(srpPeerCredentials) : srpClient.calculateSecret(srpPeerCredentials); // TODO Check if this needs to be a fixed size return BigIntegers.asUnsignedByteArray(S); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); } }
public byte[] generateCertificateSignature(byte[] hash) throws IOException { try { if (TlsUtils.isTLSv12(context)) { return signer.generateRawSignature(signatureAndHashAlgorithm, privateKey, hash); } else { return signer.generateRawSignature(privateKey, hash); } } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.internal_error, e); } }
/** * Validates the payload received from the other participant during round 1. * <p> * Must be called prior to {@link #createRound2PayloadToSend()}. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called multiple times. */ public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); } this.partnerParticipantId = round1PayloadReceived.getParticipantId(); this.gx3 = round1PayloadReceived.getGx1(); this.gx4 = round1PayloadReceived.getGx2(); BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); JPAKEUtil.validateGx4(gx4); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_1_VALIDATED; }
/** * Validates the payload received from the other participant during round 2. * <p> * Note that this DOES NOT detect a non-common password. * The only indication of a non-common password is through derivation * of different keys (which can be detected explicitly by executing round 3 and round 4) * <p> * Must be called prior to {@link #calculateKeyingMaterial()}. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public void validateRound2PayloadReceived(JPAKERound2Payload round2PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_2_VALIDATED) { throw new IllegalStateException("Validation already attempted for round2 payload for" + participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to validating Round2 payload for " + this.participantId); } BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); this.b = round2PayloadReceived.getA(); BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateGa(gB); JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_2_VALIDATED; }
/** * Authenticates the received client evidence message M1 and saves it only if correct. * To be called after calculating the secret S. * @param clientM1 the client side generated evidence message * @return A boolean indicating if the client message M1 was the expected one. * @throws CryptoException */ public boolean verifyClientEvidenceMessage(BigInteger clientM1) throws CryptoException { // Verify pre-requirements if (this.A == null || this.B == null || this.S == null) { throw new CryptoException("Impossible to compute and verify M1: " + "some data are missing from the previous operations (A,B,S)"); } // Compute the own client evidence message 'M1' BigInteger computedM1 = SRP6Util.calculateM1(digest, N, A, B, S); if (computedM1.equals(clientM1)) { this.M1 = clientM1; return true; } return false; }
/** Authenticates the server evidence message M2 received and saves it only if correct. * @param serverM2 the server side generated evidence message * @return A boolean indicating if the server message M2 was the expected one. * @throws CryptoException */ public boolean verifyServerEvidenceMessage(BigInteger serverM2) throws CryptoException { // Verify pre-requirements if (this.A == null || this.M1 == null || this.S == null) { throw new CryptoException("Impossible to compute and verify M2: " + "some data are missing from the previous operations (A,M1,S)"); } // Compute the own server evidence message 'M2' BigInteger computedM2 = SRP6Util.calculateM2(digest, N, A, M1, S); if (computedM2.equals(serverM2)) { this.M2 = serverM2; return true; } return false; }
public static byte[] processECB(byte[] key, boolean forEncryption, byte[] input) { final BufferedBlockCipher cipher = new BufferedBlockCipher(new TwofishEngine()); final KeyParameter kp = new KeyParameter(key); cipher.init(forEncryption, kp); final byte[] out = new byte[input.length]; final int len1 = cipher.processBytes(input, 0, input.length, out, 0); try { cipher.doFinal(out, len1); } catch (final CryptoException e) { throw new RuntimeException(e); } return out; }
private static byte[] operate(Encryption encryptionAlgorithm, boolean doEncrypt, byte[] subject, byte[] key, byte[] iv) throws CryptoException { // set up padded buffered cipher PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher( CipherBuilder.buildCipher(encryptionAlgorithm, doEncrypt, key, iv), new PKCS7Padding() ); // init with key and if cipher.init(doEncrypt, new ParametersWithIV(new KeyParameter(key), iv)); // construct output buffer byte[] output = new byte[cipher.getOutputSize(subject.length)]; // process all da bytes int cursor = cipher.processBytes(subject, 0, subject.length, output, 0); // process the last bytes from the buffer cipher.doFinal(output, cursor); return output; }
/** * generate a signature for the loaded message using the key we were * initialised with. */ public byte[] generateSignature() throws CryptoException { createSignatureBlock(); BigInteger t = new BigInteger(1, cipher.processBlock(block, 0, block.length)); BigInteger nSubT = kParam.getModulus().subtract(t); clearBlock(block); BigInteger v = kParam.getModulus().shiftRight(2); if (t.compareTo(nSubT) > 0) { return BigIntegers.asUnsignedByteArray((kParam.getModulus().bitLength() + 7) / 8, nSubT); } else { return BigIntegers.asUnsignedByteArray((kParam.getModulus().bitLength() + 7) / 8, t); } }
/** * Calculates the signature of a ticket and updates the given {@link Ticket} object directly. * * @throws IllegalStateException * If ticket cannot be signed. */ public void signTicket(Ticket ticket) throws IllegalStateException { byte[] serialized = TicketUtil.serialize(ticket); byte[] claimBytes = TicketUtil.deserialize(ByteBuffer.wrap(serialized)).getRight(); RSAPrivateCrtKeyParameters signingKey = keyManager.getPrivateSigningKey(); if (signingKey == null) throw new IllegalStateException("Cannot sign ticket because there is no private signing key available."); RSADigestSigner signer = new RSADigestSigner(new SHA256Digest()); signer.init(true, signingKey); signer.update(claimBytes, 0, claimBytes.length); try { byte[] signature = signer.generateSignature(); ticket.setSignature(signature); } catch (DataLengthException | CryptoException e) { throw new IllegalStateException("Cannot sign ticket", e); } }
/** * Encrypts or decrypts a given byte array of data * * @param data The data to encrypt or decrypt * @return A clear text or encrypted byte array */ private byte[] cipherData(byte[] data) { byte[] result = null; try { final byte[] buffer = new byte[this.cipher.getOutputSize(data.length)]; final int processedBytes = this.cipher.processBytes(data, 0, data.length, buffer, 0); final int finalBytes = this.cipher.doFinal(buffer, processedBytes); result = new byte[processedBytes + finalBytes]; System.arraycopy(buffer, 0, result, 0, result.length); } catch (final CryptoException e) { LOG.error("Failed to encrypt/decrypt", e); } return result; }
private void writeSignature() throws DataLengthException, CryptoException, IOException { final byte[] signatureBytes = signer.generateSignature(); final int footerLength = signatureBytes.length + 4 /* signatureBytesLength */; if (footerLength > MAX_FOOTER_LENGTH) throw new IllegalStateException(String.format("footerLength > MAX_FOOTER_LENGTH :: %s > %s", footerLength, MAX_FOOTER_LENGTH)); out.write(signatureBytes); final int signatureBytesLength = signatureBytes.length; out.write(signatureBytesLength); out.write(signatureBytesLength >>> 8); out.write(signatureBytesLength >>> 16); out.write(signatureBytesLength >>> 24); }
@Override public void close() throws IOException { if (! closed) { closed = true; final int outputSize = cipher.getOutputSize(0); ensureCipherBufferMinLength(outputSize); final int bytesWritten; try { bytesWritten = cipher.doFinal(cipherBuffer, 0); } catch (DataLengthException | IllegalStateException | CryptoException e) { throw new IOException(e); } if (bytesWritten > 0) out.write(cipherBuffer, 0, bytesWritten); if (isCloseUnderlyingStream()) out.close(); } }
public static byte[] encrypt(byte[] input, BufferedBlockCipher cipher) { synchronized(cipher) { cipher.reset(); byte[] cipherText = new byte[cipher.getOutputSize(input.length + pad.length)]; //Write out the pad int outputLen = cipher.processBytes(pad, 0, pad.length, cipherText, 0); outputLen += cipher.processBytes(input, 0, input.length, cipherText, outputLen); try { cipher.doFinal(cipherText, outputLen); } catch(CryptoException e) { Logger.die("process", e); } return cipherText; } }