/* * [Decrypt.java] * * Summary: Decrypt messages with RSA. * * Copyright: (c) 2004-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.4 2006-03-05 reformat with IntelliJ and add Javadoc. */ package com.mindprod.transporter; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; /** * Decrypt messages with RSA. *

* Using compression, salting, RSA and base64u armouring * No signing. See Transporter.java for example of use. * * @author Roedy Green, Canadian Mind Products * @version 1.4 2006-03-05 reformat with IntelliJ and add Javadoc. * @since 2004-06-08 */ public final class Decrypt extends Unwrap { /** * true if debugging */ private static final boolean DEBUGGING = false; /** * receiver's private key */ private final PrivateKey receiverPrivateKey; /** * Constructor. * * @param receiverPrivateKey receiver's private key */ public Decrypt( PrivateKey receiverPrivateKey ) { super(); this.receiverPrivateKey = receiverPrivateKey; } /** * reconstitute an encrypted message * * @param encodedBytes the message to decrypt * * @return the decrypted message. * @throws IOException if trouble decodecoding bytes. */ byte[] decrypt( byte[] encodedBytes ) throws IOException { try { if ( DEBUGGING ) { Tools.dumpBytes( "raw", encodedBytes ); } int blockLength; final ArrayList v = new ArrayList<>( 11 ); for ( int chunkStart = 0; chunkStart < encodedBytes .length; chunkStart += blockLength + 2 ) { blockLength = Tools.getBlockLength( encodedBytes, chunkStart ); /* get block without the lead length bytes */ byte[] encryptedBlock = Tools.subarray( encodedBytes, chunkStart + 2, blockLength ); /* Undo RSA encryption for each block, */ /* This is where all the time goes */ if ( DEBUGGING ) { Tools.dumpBytes( "encryptedblock", encryptedBlock ); } byte[] decryptedBlock = Tools.processWithPrivateKey( encryptedBlock, receiverPrivateKey ); if ( DEBUGGING ) { Tools.dumpBytes( "decrypted", decryptedBlock ); } /* Undo salt */ byte[] unsaltedBlock = Tools.unsalt( decryptedBlock ); if ( DEBUGGING ) { Tools.dumpBytes( "unsalted", unsaltedBlock ); } /* glue decrypted blocks back together */ v.add( unsaltedBlock ); } /* * At this point compositeMessage contains all the unscrambled * blocks, end to end, no salt or length padding. */ byte[] compositeMessage = Tools.join( v ); if ( DEBUGGING ) { Tools.dumpBytes( "composite", compositeMessage ); } return compositeMessage; } catch ( ArrayIndexOutOfBoundsException e ) { throw new IOException( "garbled message" ); } } /** * unwraps an armoured, compressed, serialised object, and decrypts it. does not parse parm=value. * * @param s base64u string. * * @return reconstituted object. * @throws IOException */ public Serializable unwrap( String s ) throws IOException { return reconstitute( decompress( decrypt( disarmour( s ) ) ) ); } }