@Test public void testModifyCiphertext() throws GeneralSecurityException { byte[] plaintext = Random.randBytes(20); for (Padding padding : Padding.values()) { HybridEncrypt hybridEncrypt = new RsaEcdsaHybridEncrypt.Builder() .withSenderSigner(senderSigner) .withRecipientPublicKey(recipientPublicKey) .withPadding(padding) .build(); HybridDecrypt hybridDecrypt = new RsaEcdsaHybridDecrypt.Builder() .withSenderVerifier(senderVerifier) .withRecipientPrivateKey(recipientPrivateKey) .withPadding(padding) .build(); byte[] ciphertext = hybridEncrypt.encrypt(plaintext, null); for (int b = 0; b < ciphertext.length; b++) { for (int bit = 0; bit < 8; bit++) { byte[] modified = Arrays.copyOf(ciphertext, ciphertext.length); modified[b] = (byte) (modified[b] ^ (1 << bit)); try { hybridDecrypt.decrypt(modified, null); int tinkSignatureBytePos = b - RsaEcdsaConstants.SIGNATURE_LENGTH_BYTES_LENGTH + 1; if (tinkSignatureBytePos == 3 || tinkSignatureBytePos == 5) { continue; } fail("Decrypting modified ciphertext should fail."); } catch (GeneralSecurityException ex) { } } } for (int length = 0; length < ciphertext.length; length++) { byte[] modified = Arrays.copyOf(ciphertext, length); try { hybridDecrypt.decrypt(modified, null); fail("Decrypting modified ciphertext should fail"); } catch (GeneralSecurityException ex) { } } } }
@Override public byte[] decrypt(byte[] ciphertext, byte[] contextInfo) throws GeneralSecurityException { if (contextInfo != null) { throw new GeneralSecurityException("contextInfo must be null because it is unused"); } try { byte[] verifiedCiphertext = deserializeAndVerify(ciphertext); return HybridRsaUtils.decrypt( verifiedCiphertext, recipientPrivateKey, padding, oaepParameterSpec); } catch (IOException e) { throw new GeneralSecurityException("decryption failed", e); } }
RsaEcdsaHybridDecrypt implements HybridDecrypt { @Override public byte[] decrypt(byte[] ciphertext, byte[] contextInfo) throws GeneralSecurityException { if (contextInfo != null) { throw new GeneralSecurityException("contextInfo must be null because it is unused"); } try { byte[] verifiedCiphertext = deserializeAndVerify(ciphertext); return HybridRsaUtils.decrypt( verifiedCiphertext, recipientPrivateKey, padding, oaepParameterSpec); } catch (IOException e) { throw new GeneralSecurityException("decryption failed", e); } } }
RsaEcdsaHybridDecrypt implements HybridDecrypt { @Override public byte[] decrypt(byte[] ciphertext, byte[] contextInfo) throws GeneralSecurityException { if (contextInfo != null) { throw new GeneralSecurityException("contextInfo must be null because it is unused"); } try { byte[] verifiedCiphertext = deserializeAndVerify(ciphertext); return HybridRsaUtils.decrypt( verifiedCiphertext, recipientPrivateKey, padding, oaepParameterSpec); } catch (IOException e) { throw new GeneralSecurityException("decryption failed", e); } } private  RsaEcdsaHybridDecrypt(Builder builder); }
RsaEcdsaHybridDecrypt implements HybridDecrypt { @Override public byte[] decrypt(byte[] ciphertext, byte[] contextInfo) throws GeneralSecurityException { if (contextInfo != null) { throw new GeneralSecurityException("contextInfo must be null because it is unused"); } try { byte[] verifiedCiphertext = deserializeAndVerify(ciphertext); return HybridRsaUtils.decrypt( verifiedCiphertext, recipientPrivateKey, padding, oaepParameterSpec); } catch (IOException e) { throw new GeneralSecurityException("decryption failed", e); } } private  RsaEcdsaHybridDecrypt(Builder builder); @Override byte[] decrypt(byte[] ciphertext, byte[] contextInfo); }
RsaEcdsaHybridDecrypt implements HybridDecrypt { @Override public byte[] decrypt(byte[] ciphertext, byte[] contextInfo) throws GeneralSecurityException { if (contextInfo != null) { throw new GeneralSecurityException("contextInfo must be null because it is unused"); } try { byte[] verifiedCiphertext = deserializeAndVerify(ciphertext); return HybridRsaUtils.decrypt( verifiedCiphertext, recipientPrivateKey, padding, oaepParameterSpec); } catch (IOException e) { throw new GeneralSecurityException("decryption failed", e); } } private  RsaEcdsaHybridDecrypt(Builder builder); @Override byte[] decrypt(byte[] ciphertext, byte[] contextInfo);  }