All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.util.JournaledAlgorithm Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for Java 1.8 and later with debug enabled.

The newest version!
package org.bouncycastle.crypto.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.SecureRandom;

import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.util.Encodable;
import org.bouncycastle.util.io.Streams;

/**
 * JournaledAlgorithm keeps state of the JournalingSecureRandom and the
 * AlgorithmIdentifier necessary to fully resume an encryption session. This
 * class can be used to retrieve a session even if a process is completely
 * stopped. NOTE: This should be used with a shutdown hook to save the state of
 * the journaling and the algorithm identifier even in the case of a forced
 * shutdown.
 * 

* The raw encoding is in ASN.1 format. *

*

* Details: Use serialization of critical parameters of the the * JournalingSecureRandom and AlgorithmIdentifier. Because these two classes are * not serializable, create interior class to serialize only the critical * parameters in the form of byte[] arrays */ public class JournaledAlgorithm implements Encodable, Serializable { private transient JournalingSecureRandom journaling; private transient AlgorithmIdentifier algID; public JournaledAlgorithm(AlgorithmIdentifier aid, JournalingSecureRandom journaling) { if (aid == null) { throw new NullPointerException("AlgorithmIdentifier passed to JournaledAlgorithm is null"); } else if (journaling == null) { throw new NullPointerException("JournalingSecureRandom passed to JournaledAlgorithm is null"); } this.journaling = journaling; this.algID = aid; } /** * Construct from a previous encoding, using CryptoServicesRegistrar.getSecureRandom() as the backup source of entropy. * * @param encoding raw encoding of a previous JournaledAlgorithm. */ public JournaledAlgorithm(byte[] encoding) { this(encoding, CryptoServicesRegistrar.getSecureRandom()); } /** * Construct from a previous encoding, using the passed in random as a source for when the existing entropy runs out. * * @param encoding raw encoding of a previous JournaledAlgorithm. * @param random back up source of entropy. */ public JournaledAlgorithm(byte[] encoding, SecureRandom random) { if (encoding == null) { throw new NullPointerException("encoding passed to JournaledAlgorithm is null"); } else if (random == null) { throw new NullPointerException("random passed to JournaledAlgorithm is null"); } initFromEncoding(encoding, random); } private void initFromEncoding(byte[] encoding, SecureRandom random) { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); this.algID = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); this.journaling = new JournalingSecureRandom(ASN1OctetString.getInstance(seq.getObjectAt(1)).getOctets(), random); } public JournalingSecureRandom getJournalingSecureRandom() { return journaling; } public AlgorithmIdentifier getAlgorithmIdentifier() { return algID; } /** * Store state of JournalingSecureRandom and AlgorithmIdentifier in temporary * file * * @param tempfile * @throws IOException */ public void storeState(File tempfile) throws IOException { if (tempfile == null) { throw new NullPointerException("file for storage is null in JournaledAlgorithm"); } // Extract key information in byte[] form FileOutputStream fOut = new FileOutputStream(tempfile); try { storeState(fOut); } finally { fOut.close(); } } public void storeState(OutputStream out) throws IOException { if (out == null) { throw new NullPointerException("output stream for storage is null in JournaledAlgorithm"); } out.write(this.getEncoded()); } public static JournaledAlgorithm getState(InputStream stateIn, SecureRandom random) throws IOException, ClassNotFoundException { if (stateIn == null) { throw new NullPointerException("stream for loading is null in JournaledAlgorithm"); } InputStream fIn = new BufferedInputStream(stateIn); try { return new JournaledAlgorithm(Streams.readAll(fIn), random); } finally { fIn.close(); } } /** * Reconstructs JournaledAlgorithm session from file containing it's raw encoding. * * @param tempfile temporary file containing serialized state * @return * @throws IOException * @throws ClassNotFoundException */ public static JournaledAlgorithm getState(File tempfile, SecureRandom random) throws IOException, ClassNotFoundException { if (tempfile == null) { throw new NullPointerException("File for loading is null in JournaledAlgorithm"); } InputStream fIn = new BufferedInputStream(new FileInputStream(tempfile)); try { return new JournaledAlgorithm(Streams.readAll(fIn), random); } finally { fIn.close(); } } public byte[] getEncoded() throws IOException { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(algID); v.add(new DEROctetString(journaling.getFullTranscript())); return new DERSequence(v).getEncoded(); } private void readObject( ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); initFromEncoding((byte[])in.readObject(), CryptoServicesRegistrar.getSecureRandom()); } private void writeObject( ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(getEncoded()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy