package com.jessecoyle; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Created by jcoyle on 2/1/16. */ public class CredStashBouncyCastleCrypto implements CredStashCrypto { @Override public byte[] decrypt(byte[] key, byte[] contents) { return encryptOrDecrypt(key, contents, false); } @Override public byte[] encrypt(byte[] key, byte[] contents) { return encryptOrDecrypt(key, contents, true); } private byte[] encryptOrDecrypt(byte[] key, byte[] contents, boolean forEncryption) { // Credstash uses standard AES BlockCipher engine = new AESFastEngine(); // Credstash uses CTR mode StreamBlockCipher cipher = new SICBlockCipher(engine); cipher.init(forEncryption, new ParametersWithIV(new KeyParameter(key), INITIALIZATION_VECTOR)); byte[] resultBytes = new byte[contents.length]; int contentsOffset = 0; int resultOffset = 0; cipher.processBytes(contents, contentsOffset, contents.length, resultBytes, resultOffset); return resultBytes; } @Override public byte[] digest(byte[] key, byte[] contents) { // Credstash uses SHA-256 SHA256Digest digest = new SHA256Digest(); // Credstash uses HMAC HMac mac = new HMac(digest); byte[] resultBytes = new byte[mac.getMacSize()]; mac.init(new KeyParameter(key)); mac.update(contents, 0, contents.length); mac.doFinal(resultBytes, 0); return resultBytes; } }