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);
 }
Beispiel #3
0
 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;
   }
 }
Beispiel #4
0
  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();
   }
 }
Beispiel #9
0
  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;
  }
Beispiel #11
0
 private final void bufferInputBytes(byte[] in, int inOfs, int len) {
   System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
   padBufferLen += len;
   bytesBuffered += len;
 }