public void writeSession(HttpServletRequest request, HttpServletResponse response) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { SparkHttpRequestWrapper sparkRequest = (SparkHttpRequestWrapper) request; if (!sparkRequest.sessionAccessed()) return; CookieSession session = (CookieSession) request.getSession(); // serialize session byte[] sessionBytes = conf.asByteArray(session); // encrypt content final Cipher symmetricalCipher = Cipher.getInstance(symmetricEncryptionAlgorithm); symmetricalCipher.init(Cipher.ENCRYPT_MODE, this.symmetricEncryptionKey); byte[] encryptedBytes = symmetricalCipher.doFinal(sessionBytes); // sign content byte[] signature = sign(encryptedBytes); byte[] cookieContent = new byte[encryptedBytes.length + signature.length]; System.arraycopy(encryptedBytes, 0, cookieContent, 0, encryptedBytes.length); System.arraycopy( signature, 0, cookieContent, cookieContent.length - signature.length, signature.length); String base64CookieContent = Base64.getEncoder().encodeToString(cookieContent); addCookie(base64CookieContent, response); }
private static void concat(byte[] src, byte[] dst, int start, int len) { if (src.length == 0) { return; } int loop = len / src.length; int off, i; for (i = 0, off = 0; i < loop; i++, off += src.length) System.arraycopy(src, 0, dst, off + start, src.length); System.arraycopy(src, 0, dst, off + start, len - off); }
public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = javax.crypto.Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); synchronized (javax.crypto.Cipher.class) { cipher.init( (mode == ENCRYPT_MODE ? javax.crypto.Cipher.ENCRYPT_MODE : javax.crypto.Cipher.DECRYPT_MODE), _key); } byte[] foo = new byte[1]; for (int i = 0; i < skip; i++) { cipher.update(foo, 0, 1, foo, 0); } } catch (Exception e) { cipher = null; throw e; } }
private static int runEncryptCase( String k_hex, String p_hex, String iv_hex, String aad_hex, String c_hex, String t_hex, String hint) { byte[] K = hexStrToBytes(k_hex); byte[] P = hexStrToBytes(p_hex); byte[] IV = hexStrToBytes(iv_hex); byte[] AAD = hexStrToBytes(aad_hex); byte[] C = hexStrToBytes(c_hex); byte[] T = hexStrToBytes(t_hex); byte[] output = gcmEncrypt(K, P, AAD, IV); byte[] cipher = new byte[output.length - BLOCK_SIZE]; byte[] tag = new byte[BLOCK_SIZE]; System.arraycopy(output, 0, cipher, 0, output.length - BLOCK_SIZE); System.arraycopy(output, output.length - BLOCK_SIZE, tag, 0, BLOCK_SIZE); System.out.println("-------------------------------------"); int errNo = 0; errNo = compareArrays(cipher, C); if (errNo > 0) { System.out.println(hint + " data encryption failed!"); } else { System.out.println(hint + " data encryption passed!"); } if (compareArrays(tag, T) > 0) { errNo++; System.out.println(hint + " tag verification failed!"); } else { System.out.println(hint + " tag verification passed!"); } return errNo; }
private static byte[] expandToOneBlock(byte[] in, int inOfs, int len) { if (len > AES_BLOCK_SIZE) { throw new ProviderException("input " + len + " too long"); } if (len == AES_BLOCK_SIZE && inOfs == 0) { return in; } else { byte[] paddedIn = new byte[AES_BLOCK_SIZE]; System.arraycopy(in, inOfs, paddedIn, 0, len); return paddedIn; } }
/** * Performs decryption operation for the last time. * * <p>NOTE: For cipher feedback modes which does not perform special handling for the last few * blocks, this is essentially the same as <code>encrypt(...)</code>. Given most modes do not do * special handling, the default impl for this method is to simply call <code>decrypt(...)</code>. * * @param in the input buffer with the data to be decrypted * @param inOfs the offset in <code>cipher</code> * @param len the length of the input data * @param out the buffer for the decryption result * @param outOfs the offset in <code>plain</code> * @return the number of bytes placed into the <code>out</code> buffer */ int decryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs) throws IllegalBlockSizeException, AEADBadTagException, ShortBufferException { if (len < tagLenBytes) { throw new AEADBadTagException("Input too short - need tag"); } if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) { throw new ShortBufferException("Output buffer too small"); } processAAD(); if (len != 0) { ibuffer.write(in, inOfs, len); } // refresh 'in' to all buffered-up bytes in = ibuffer.toByteArray(); inOfs = 0; len = in.length; ibuffer.reset(); byte[] tag = new byte[tagLenBytes]; // get the trailing tag bytes from 'in' System.arraycopy(in, len - tagLenBytes, tag, 0, tagLenBytes); len -= tagLenBytes; if (len > 0) { doLastBlock(in, inOfs, len, out, outOfs, false); } byte[] lengthBlock = getLengthBlock(sizeOfAAD * 8, processed * 8); ghashAllToS.update(lengthBlock); byte[] s = ghashAllToS.digest(); byte[] sOut = new byte[s.length]; GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock); gctrForSToTag.doFinal(s, 0, s.length, sOut, 0); for (int i = 0; i < tagLenBytes; i++) { if (tag[i] != sOut[i]) { throw new AEADBadTagException("Tag mismatch!"); } } return len; }
/** * Performs encryption operation for the last time. * * @param in the input buffer with the data to be encrypted * @param inOfs the offset in <code>in</code> * @param len the length of the input data * @param out the buffer for the encryption result * @param outOfs the offset in <code>out</code> * @return the number of bytes placed into the <code>out</code> buffer */ int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs) throws IllegalBlockSizeException, ShortBufferException { if (out.length - outOfs < (len + tagLenBytes)) { throw new ShortBufferException("Output buffer too small"); } processAAD(); if (len > 0) { doLastBlock(in, inOfs, len, out, outOfs, true); } byte[] lengthBlock = getLengthBlock(sizeOfAAD * 8, processed * 8); ghashAllToS.update(lengthBlock); byte[] s = ghashAllToS.digest(); byte[] sOut = new byte[s.length]; GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock); gctrForSToTag.doFinal(s, 0, s.length, sOut, 0); System.arraycopy(sOut, 0, out, (outOfs + len), tagLenBytes); return (len + tagLenBytes); }
private int implDoFinal(byte[] out, int outOfs, int outLen) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { int requiredOutLen = doFinalLength(0); if (outLen < requiredOutLen) { throw new ShortBufferException(); } try { ensureInitialized(); int k = 0; if (encrypt) { if (paddingObj != null) { int actualPadLen = paddingObj.setPaddingBytes(padBuffer, requiredOutLen - bytesBuffered); k = token.p11.C_EncryptUpdate( session.id(), 0, padBuffer, 0, actualPadLen, 0, out, outOfs, outLen); } k += token.p11.C_EncryptFinal(session.id(), 0, out, (outOfs + k), (outLen - k)); } else { if (paddingObj != null) { if (padBufferLen != 0) { k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, 0, padBuffer, 0, padBuffer.length); } k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k, padBuffer.length - k); int actualPadLen = paddingObj.unpad(padBuffer, k); k -= actualPadLen; System.arraycopy(padBuffer, 0, out, outOfs, k); } else { k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs, outLen); } } return k; } catch (PKCS11Exception e) { handleException(e); throw new ProviderException("doFinal() failed", e); } finally { reset(); } }
public void init(int mode, byte[] key, byte[] iv) throws Exception { String pad = "NoPadding"; byte[] tmp; if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = javax.crypto.Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); cipher.init( (mode == ENCRYPT_MODE ? javax.crypto.Cipher.ENCRYPT_MODE : javax.crypto.Cipher.DECRYPT_MODE), _key); } catch (Exception e) { cipher = null; throw e; } }
// Uses supplied hash algorithm static byte[] derive( char[] chars, byte[] salt, int ic, int n, int type, String hashAlgo, int blockLength) { // Add in trailing NULL terminator. Special case: // no terminator if password is "\0". int length = chars.length * 2; if (length == 2 && chars[0] == 0) { chars = new char[0]; length = 0; } else { length += 2; } byte[] passwd = new byte[length]; for (int i = 0, j = 0; i < chars.length; i++, j += 2) { passwd[j] = (byte) ((chars[i] >>> 8) & 0xFF); passwd[j + 1] = (byte) (chars[i] & 0xFF); } byte[] key = new byte[n]; try { MessageDigest sha = MessageDigest.getInstance(hashAlgo); int v = blockLength; int u = sha.getDigestLength(); int c = roundup(n, u) / u; byte[] D = new byte[v]; int s = roundup(salt.length, v); int p = roundup(passwd.length, v); byte[] I = new byte[s + p]; Arrays.fill(D, (byte) type); concat(salt, I, 0, s); concat(passwd, I, s, p); byte[] Ai; byte[] B = new byte[v]; byte[] tmp = new byte[v]; int i = 0; for (; ; i++, n -= u) { sha.update(D); sha.update(I); Ai = sha.digest(); for (int r = 1; r < ic; r++) Ai = sha.digest(Ai); System.arraycopy(Ai, 0, key, u * i, Math.min(n, u)); if (i + 1 == c) break; concat(Ai, B, 0, B.length); BigInteger B1; B1 = new BigInteger(1, B).add(BigInteger.ONE); for (int j = 0; j < I.length; j += v) { BigInteger Ij; int trunc; if (tmp.length != v) tmp = new byte[v]; System.arraycopy(I, j, tmp, 0, v); Ij = new BigInteger(1, tmp); Ij = Ij.add(B1); tmp = Ij.toByteArray(); trunc = tmp.length - v; if (trunc >= 0) { System.arraycopy(tmp, trunc, I, j, v); } else if (trunc < 0) { Arrays.fill(I, j, j + (-trunc), (byte) 0); System.arraycopy(tmp, 0, I, j + (-trunc), tmp.length); } } } } catch (Exception e) { throw new RuntimeException("internal error: " + e); } return key; }
private final void bufferInputBytes(byte[] in, int inOfs, int len) { System.arraycopy(in, inOfs, padBuffer, padBufferLen, len); padBufferLen += len; bytesBuffered += len; }