Beispiel #1
0
 public byte[] sign() throws BadPaddingException, IllegalBlockSizeException {
   cipher.update(beforeAlgorithmIdBytes);
   cipher.update(algorithmIdBytes);
   cipher.update(afterAlgorithmIdBytes);
   cipher.update(md.digest());
   return cipher.doFinal();
 }
Beispiel #2
0
  public static byte[] encryptbytes(
      byte[] bytefile, SecretKey secretKey, byte[] nonceBuffer, int offset) {

    byte[] byteCipherText = null;
    try {
      final byte[] plaintext = bytefile;
      final byte[] nonce = nonceBuffer;
      final byte[] ciphertext = new byte[plaintext.length];

      Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
      final int skip = offset % BLOCK_SIZE;
      final IvParameterSpec nonceIV =
          calculateIVForOffset(
              generateIVFromNonce(nonce, 0, NONCE_SIZE, cipher.getBlockSize()), offset - skip);
      cipher.init(Cipher.ENCRYPT_MODE, secretKey, nonceIV);
      final byte[] skipBuffer = new byte[skip];
      cipher.update(skipBuffer, 0, skip, skipBuffer);
      cipher.doFinal(plaintext, 0, plaintext.length, ciphertext);

      byteCipherText = ciphertext;
    } catch (final GeneralSecurityException e) {
      throw new IllegalStateException("Missing basic functionality from Java runtime", e);
    }
    return byteCipherText;
  }
  public static byte[] compute(SecretKey key, byte[] message)
      throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
          ShortBufferException, IllegalBlockSizeException, BadPaddingException,
          InvalidAlgorithmParameterException {
    byte finalBlock[] = new byte[16];
    int numCBC = message.length / 16;
    int leftOver = message.length % 16;
    ByteBuffer zeroBuffer = ByteBuffer.wrap(ZERO_128);
    byte[] encryptZero = encryptBlock(key, zeroBuffer);
    byte[] k1 = getSubkey(encryptZero);
    if (leftOver != 0) {
      for (int i = 0; i < leftOver; i++) {
        finalBlock[i] = message[numCBC * 16 + i];
      }
      finalBlock[leftOver] = (byte) 0x80;
      // This can probably be skipped, since java initializes to zero.
      for (int j = leftOver + 1; j < 16; j++) {
        finalBlock[j] = 0;
      }
      xorArrayInPlace(finalBlock, k1);
    } else {
      byte k2[] = getSubkey(k1);
      xorArrayInPlace(finalBlock, k2);
    }

    Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
    c.init(Cipher.ENCRYPT_MODE, key, ZERO_IV);
    if (numCBC > 0) {
      c.update(message, 0, numCBC * 16);
    }
    return c.doFinal(finalBlock);
  }
Beispiel #4
0
  private static byte[] gcmEncrypt(byte[] key, byte[] plainText, byte[] aad, byte[] iv) {
    byte[] cipherText = new byte[plainText.length + 16];
    try {

      SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
      GCMParameterSpec gcmSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
      Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + MODE + "/NoPadding");
      cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);

      if (aad != null && aad.length != 0) {
        cipher.updateAAD(aad);
      }

      // if has more than one blocks, test cipher.update
      if (plainText.length > 16) {
        cipher.update(plainText, 0, 16, cipherText, 0);
        cipher.doFinal(plainText, 16, plainText.length - 16, cipherText, 16);
      } else {
        // doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
        cipher.doFinal(plainText, 0, plainText.length, cipherText, 0);
      }

    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return cipherText;
  }
  private void Encrypter(String data) throws Exception {

    // Security.addProvider(new MainActivity().BouncyCastleProvider());

    byte[] input = data.getBytes();
    byte[] keyBytes = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

    int keySize = keyBytes.length;
    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");

    mTxtInput.setText(new String(data));
    // System.out.println(new String(input));

    // encryption pass
    cipher.init(Cipher.ENCRYPT_MODE, key);

    byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
    int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
    ctLength += cipher.doFinal(cipherText, ctLength);

    // System.out.println(new String(cipherText));
    // System.out.println(ctLength);

    mTxtCipher.setText(new String(cipherText));
    mTxtCtLenght.setText(String.valueOf(ctLength));
    // decryption pass
    String x = new String(cipherText);
  }
Beispiel #6
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;
   }
 }
  /**
   * Do actual encryption/decryption from source to destination file.
   *
   * @return <code>true</code> if file is successfully encrypted/decrypted, otherwise <code>false
   *     </code>.
   */
  public boolean process() {
    try {
      InputStream inputStream = Files.newInputStream(inputPath, StandardOpenOption.READ);
      OutputStream outputStream = Files.newOutputStream(outputPath, StandardOpenOption.WRITE);

      byte[] inputBuffer = new byte[4096];
      while (true) {
        int byteCount = inputStream.read(inputBuffer);
        if (byteCount < 1) break;

        byte[] outputBuffer = new byte[4096];
        int outputByteCount = cipher.update(inputBuffer, 0, byteCount, outputBuffer);
        outputStream.write(outputBuffer, 0, outputByteCount);
      }

      byte[] outputBuffer = new byte[4096];
      int outputByteCount = cipher.doFinal(outputBuffer, 0);
      outputStream.write(outputBuffer, 0, outputByteCount);
    } catch (ShortBufferException e) {
      return false;
    } catch (IllegalBlockSizeException e) {
      return false;
    } catch (BadPaddingException e) {
      return false;
    } catch (IOException e) {
      return false;
    }

    return true;
  }
Beispiel #8
0
  @Override
  public byte readByte() {
    if (!isOpen()) {
      return -1;
    }

    if (filename == null && count > maxCount) {
      open = false;
      return -1;
    }

    byte prng = -1;

    /*
     * encrypt file if exists
     */
    if (filename != null) {
      if (countLastRead == actualSize) { // end of buffer?
        super.readByte(); // read & fill buffer from file
        if (!isOpen()) {
          return -1;
        }
        countLastRead = 0;
        try {
          algo.update(buffer, 0, actualSize, buffer);
        } catch (ShortBufferException e) {
          throw new IllegalStateException(e);
        } // encrypt it
      }

      prng = buffer[countLastRead++];
      count++;
      return prng;
    }

    /*
     * we have no real filename to encrypt
     */
    if (outAlgoBufferIx == outAlgoBuffer.length) {
      outAlgoBuffer = algo.update(inAlgoBuffer);
      outAlgoBufferIx = 0;
    }

    prng = outAlgoBuffer[outAlgoBufferIx++];
    count++;
    return prng;
  }
  public void run() {
    try {
      ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
      ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

      BigInteger bg = dhSpec.getG();
      BigInteger bp = dhSpec.getP();
      oos.writeObject(bg);
      oos.writeObject(bp);

      KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
      kpg.initialize(1024);
      KeyPair kpa = (KeyPair) ois.readObject();
      KeyAgreement dh = KeyAgreement.getInstance("DH");
      KeyPair kp = kpg.generateKeyPair();

      oos.writeObject(kp);

      dh.init(kp.getPrivate());
      Key pk = dh.doPhase(kpa.getPublic(), true);

      MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
      byte[] rawbits = sha256.digest(dh.generateSecret());

      Cipher c = Cipher.getInstance(CIPHER_MODE);
      SecretKey key = new SecretKeySpec(rawbits, 0, 16, "AES");
      byte ivbits[] = (byte[]) ois.readObject();
      IvParameterSpec iv = new IvParameterSpec(ivbits);
      c.init(Cipher.DECRYPT_MODE, key, iv);

      Mac m = Mac.getInstance("HmacSHA1");
      SecretKey mackey = new SecretKeySpec(rawbits, 16, 16, "HmacSHA1");
      m.init(mackey);

      byte ciphertext[], cleartext[], mac[];
      try {
        while (true) {
          ciphertext = (byte[]) ois.readObject();
          mac = (byte[]) ois.readObject();
          if (Arrays.equals(mac, m.doFinal(ciphertext))) {
            cleartext = c.update(ciphertext);
            System.out.println(ct + " : " + new String(cleartext, "UTF-8"));
          } else {
            // System.exit(1);
            System.out.println(ct + "error");
          }
        }
      } catch (EOFException e) {
        cleartext = c.doFinal();
        System.out.println(ct + " : " + new String(cleartext, "UTF-8"));
        System.out.println("[" + ct + "]");
      } finally {
        if (ois != null) ois.close();
        if (oos != null) oos.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Beispiel #10
0
  private void testGCMParameterSpecWithMultipleUpdates(
      byte[] K, byte[] N, byte[] A, byte[] P, byte[] C) throws Exception {
    Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC");
    SecretKeySpec key = new SecretKeySpec(K, "AES");
    SecureRandom random = new SecureRandom();

    // GCMParameterSpec mapped to AEADParameters and overrides default MAC
    // size
    GCMParameterSpec spec = new GCMParameterSpec(128, N);

    for (int i = 900; i != 1024; i++) {
      byte[] message = new byte[i];

      random.nextBytes(message);

      eax.init(Cipher.ENCRYPT_MODE, key, spec);

      byte[] out = new byte[eax.getOutputSize(i)];

      int offSet = 0;

      int count;
      for (count = 0; count < i / 21; count++) {
        offSet += eax.update(message, count * 21, 21, out, offSet);
      }

      offSet += eax.doFinal(message, count * 21, i - (count * 21), out, offSet);

      byte[] dec = new byte[i];
      int len = offSet;

      eax.init(Cipher.DECRYPT_MODE, key, spec);

      offSet = 0;
      for (count = 0; count < len / 10; count++) {
        offSet += eax.update(out, count * 10, 10, dec, offSet);
      }

      offSet += eax.doFinal(out, count * 10, len - (count * 10), dec, offSet);

      if (!Arrays.areEqual(message, dec) || offSet != message.length) {
        fail("message mismatch");
      }
    }
  }
Beispiel #11
0
  public static void crypt(String inFilename, String outFilename, int mode) {
    InputStream in = null;
    OutputStream out = null;
    ObjectInputStream keyin = null;
    try {
      in = new FileInputStream(inFilename);
      out = new FileOutputStream(outFilename);
      keyin = new ObjectInputStream(new FileInputStream(keyFilename));
      // 获取到密钥
      Key key = (Key) keyin.readObject();
      // 使用AES算法获取密码对象
      Cipher cipher = Cipher.getInstance("AES");
      // 通过设置模式和密钥来初始化
      cipher.init(mode, key);

      // 获取密码块大小,16
      int blockSize = cipher.getBlockSize();
      // 该密码块对应的输出缓存区大小,用于存放密码对象输出的数据块
      int outputSize = cipher.getOutputSize(blockSize);
      byte[] inBytes = new byte[blockSize];
      byte[] outBytes = new byte[outputSize];
      int length = 0;

      boolean more = true;
      while (more) {
        length = in.read(inBytes);
        // 如果能读到blockSize大小的块
        if (length == blockSize) {
          // 数据块存入outBytes
          int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
          out.write(outBytes, 0, outLength);
        } else {
          more = false;
        }
      }
      // 如果最后一个输入数据块的字节数小于blockSize,剩下的字节将会自动填充
      if (length > 0) {
        outBytes = cipher.doFinal(inBytes, 0, length);
      } else {
        outBytes = cipher.doFinal();
      }
      out.write(outBytes);

    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (GeneralSecurityException e) {
      e.printStackTrace();
    } finally {
      Closer.close(in);
      Closer.close(out);
      Closer.close(keyin);
    }
  }
  private byte[] fetchSymmetricKeyData(PGPPrivateKey privKey, Provider asymProvider)
      throws PGPException {
    Cipher c1 = getKeyCipher(keyData.getAlgorithm(), asymProvider);

    try {
      c1.init(Cipher.DECRYPT_MODE, privKey.getKey());
    } catch (InvalidKeyException e) {
      throw new PGPException("error setting asymmetric cipher", e);
    }

    BigInteger[] keyD = keyData.getEncSessionKey();

    if (keyData.getAlgorithm() == PGPPublicKey.RSA_ENCRYPT
        || keyData.getAlgorithm() == PGPPublicKey.RSA_GENERAL) {
      byte[] bi = keyD[0].toByteArray();

      if (bi[0] == 0) {
        c1.update(bi, 1, bi.length - 1);
      } else {
        c1.update(bi);
      }
    } else {
      ElGamalKey k = (ElGamalKey) privKey.getKey();
      int size = (k.getParameters().getP().bitLength() + 7) / 8;
      byte[] tmp = new byte[size];

      byte[] bi = keyD[0].toByteArray();
      if (bi.length > size) {
        c1.update(bi, 1, bi.length - 1);
      } else {
        System.arraycopy(bi, 0, tmp, tmp.length - bi.length, bi.length);
        c1.update(tmp);
      }

      bi = keyD[1].toByteArray();
      for (int i = 0; i != tmp.length; i++) {
        tmp[i] = 0;
      }

      if (bi.length > size) {
        c1.update(bi, 1, bi.length - 1);
      } else {
        System.arraycopy(bi, 0, tmp, tmp.length - bi.length, bi.length);
        c1.update(tmp);
      }
    }

    byte[] plain;
    try {
      plain = c1.doFinal();
    } catch (Exception e) {
      throw new PGPException("exception decrypting secret key", e);
    }

    if (!confirmCheckSum(plain)) {
      throw new PGPKeyValidationException("key checksum failed");
    }

    return plain;
  }
  public void wrap(NextFilter nextFilter, WriteRequest writeRequest, IoBuffer buf)
      throws AuthException {
    int start = buf.position();
    int len = buf.remaining() - LINE_TERMINATOR.length;
    if (len == 0) throw new AuthException("Decryption failed");

    // HMAC(Ki, {SeqNum, msg})[0..9]
    byte[] originalMessage = new byte[len];
    buf.get(originalMessage);
    byte[] mac = AuthDigestMD5IoFilter.computeMACBlock(session, originalMessage, false);

    // Calculate padding
    int bs = encCipher.getBlockSize();
    byte[] padding;

    if (bs > 1) {
      int pad = bs - ((len + 10) % bs); // add 10 for HMAC[0..9]
      padding = new byte[pad];
      for (int i = 0; i < pad; i++) padding[i] = (byte) pad;
    } else padding = EMPTY_BYTE_ARRAY;

    byte[] toBeEncrypted = new byte[len + padding.length + 10];

    // {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])}
    System.arraycopy(originalMessage, start, toBeEncrypted, 0, len);
    System.arraycopy(padding, 0, toBeEncrypted, len, padding.length);
    System.arraycopy(mac, 0, toBeEncrypted, len + padding.length, 10);

    // CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])})
    byte[] cipherBlock;
    try {
      // Do CBC (chaining) across packets
      cipherBlock = encCipher.update(toBeEncrypted);

      // update() can return null
      if (cipherBlock == null) throw new IllegalBlockSizeException("" + toBeEncrypted.length);
    } catch (IllegalBlockSizeException e) {
      throw new AuthException("Invalid block size for cipher", e);
    }

    IoBuffer out = IoBuffer.allocate(cipherBlock.length + 2 + 4 + LINE_TERMINATOR.length);
    out.put(cipherBlock);
    out.put(mac, 10, 6); // messageType & sequenceNum
    out.put(LINE_TERMINATOR);
    out.flip();

    if (out.limit()
        > ((Integer) session.getAttribute(AuthDigestMD5Command.CLIENT_MAXBUF)).intValue())
      throw new AuthException("Data exceeds client maxbuf capability");

    nextFilter.filterWrite(session, new DefaultWriteRequest(out, writeRequest.getFuture()));
  }
  private static void crypt(InputStream input, OutputStream out, Cipher cipher)
      throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException {
    int blockSize = cipher.getBlockSize();
    int outputSize = cipher.getOutputSize(blockSize);

    int inLength;
    byte[] inBytes = new byte[blockSize];
    byte[] outBytes = new byte[outputSize];
    while ((inLength = IOUtils.read(input, inBytes)) != 0) {
      int outLength = cipher.update(inBytes, 0, inLength, outBytes);
      out.write(outBytes, 0, outLength);
    }
    IOUtils.write(cipher.doFinal(), out);
  }
Beispiel #15
0
  /**
   * Use the specified TripleDES key to decrypt bytes ready from the input stream and write them to
   * the output stream. This method uses uses Cipher directly to show how it can be done without
   * CipherInputStream and CipherOutputStream.
   */
  public static void decrypt(SecretKey key, InputStream in, OutputStream out)
      throws NoSuchAlgorithmException, InvalidKeyException, IOException, IllegalBlockSizeException,
          NoSuchPaddingException, BadPaddingException {
    // Create and initialize the decryption engine
    Cipher cipher = Cipher.getInstance("DESede");
    cipher.init(Cipher.DECRYPT_MODE, key);

    // Read bytes, decrypt, and write them out.
    byte[] buffer = new byte[2048];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
      out.write(cipher.update(buffer, 0, bytesRead));
    }

    // Write out the final bunch of decrypted bytes
    out.write(cipher.doFinal());
    out.flush();
  }
  private void Decryptor(byte[] cipherText) throws Exception {

    byte[] keyBytes = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
    int keySize = keyBytes.length;
    int x = cipherText.length;

    // decryption pass
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] plainText = new byte[cipher.getOutputSize(x)];
    int ptLength = cipher.update(cipherText, 0, x, plainText, 0);
    ptLength += cipher.doFinal(plainText, ptLength);

    mTxtPlainText.setText(new String(plainText));
    // mTxtPtLength.setText(String.valueOf(ptLength));
  }
Beispiel #17
0
  /**
   * Decrypts a given byte stream using the AES cipher, CBC mode, and PKCS5 Padding algorithms.
   *
   * @param input - Bytes to be decrypted
   * @param key - Symmetric key to decrypt
   * @param iv - Initialization vector
   * @return decrypted byte stream
   * @throws NoSuchAlgorithmException
   * @throws NoSuchPaddingException
   * @throws InvalidKeyException
   * @throws InvalidAlgorithmParameterException
   * @throws ShortBufferException
   * @throws IllegalBlockSizeException
   * @throws BadPaddingException
   * @throws UnsupportedEncodingException
   */
  public static byte[] AESCBCdecrypt(byte[] input, Key key, byte[] iv)
      throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
          InvalidAlgorithmParameterException, ShortBufferException, IllegalBlockSizeException,
          BadPaddingException, UnsupportedEncodingException {
    int plaintext_len;
    byte[] keyBytes, plaintext;
    SecretKeySpec keySpec;
    IvParameterSpec ivSpec;
    Cipher cipher;

    keyBytes = key.getBytes();
    keySpec = new SecretKeySpec(keyBytes, "AES");
    ivSpec = new IvParameterSpec(iv);
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
    plaintext = new byte[cipher.getOutputSize(input.length)];

    plaintext_len = cipher.update(input, 0, input.length, plaintext, 0);
    plaintext_len += cipher.doFinal(plaintext, plaintext_len);
    return plaintext;
  }
Beispiel #18
0
  /**
   * Uses a cipher to transform the bytes in an input stream and sends the transformed bytes to an
   * output stream.
   *
   * @param in the input stream
   * @param out the output stream
   * @param cipher the cipher that transforms the bytes
   */
  public static void crypt(InputStream in, OutputStream out, Cipher cipher)
      throws IOException, GeneralSecurityException {
    int blockSize = cipher.getBlockSize();
    int outputSize = cipher.getOutputSize(blockSize);
    byte[] inBytes = new byte[blockSize];
    byte[] outBytes = new byte[outputSize];

    int inLength = 0;
    ;
    boolean more = true;
    while (more) {
      inLength = in.read(inBytes);
      if (inLength == blockSize) {
        int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
        out.write(outBytes, 0, outLength);
      } else more = false;
    }
    if (inLength > 0) outBytes = cipher.doFinal(inBytes, 0, inLength);
    else outBytes = cipher.doFinal();
    out.write(outBytes);
  }
  @Override
  public void handle(Address address, ByteBuffer buffer) {
    if ((cipher == null) || (mac == null)) {
      sequence++;
      wrappee.handle(address, buffer);
      return;
    }

    ByteBuffer sequenceBuffer = ByteBuffer.allocate(Ints.BYTES);
    sequenceBuffer.putInt(sequence);
    sequence++;
    sequenceBuffer.flip();

    mac.reset();
    mac.update(sequenceBuffer);
    int p = buffer.position();
    mac.update(buffer);
    buffer.position(p);

    byte[] calculatedMac = new byte[mac.getMacLength()];
    try {
      mac.doFinal(calculatedMac, 0);
    } catch (ShortBufferException e) {
      throw new RuntimeException(e);
    } catch (IllegalStateException e) {
      throw new RuntimeException(e);
    }

    ByteBuffer b = ByteBuffer.allocate(buffer.remaining() + calculatedMac.length);
    try {
      cipher.update(buffer, b);
    } catch (ShortBufferException e) {
      throw new RuntimeException(e);
    }
    b.put(calculatedMac);
    b.flip();

    wrappee.handle(address, b);
  }
Beispiel #20
0
    /**
     * Verify Bryan's public key.
     *
     * @param pubKey - public key received through TCP
     * @param digest - signature received through TCP
     * @return true if it is verified successfully; false otherwise
     */
    public boolean verifyBryanPubKey(PublicKey pubKey, byte[] digest) {

      try {
        String bryanStr = "bryan";
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(bryanStr.getBytes(StandardCharsets.US_ASCII));
        md5.update(pubKey.getEncoded());

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, berisignPubKey);
        cipher.update(digest);

        byte[] bryanDigest = md5.digest();
        byte[] berisignDigest = cipher.doFinal();

        if (Arrays.equals(bryanDigest, berisignDigest)) {
          this.bryanPubKey = pubKey;
        } else {
          return false;
        }
      } catch (NoSuchAlgorithmException e) {
        System.out.println("Error: No algorithm entered exists.");
        return false;
      } catch (NoSuchPaddingException e) {
        System.out.println("Error: transformation contains a padding scheme is not available.");
        return false;
      } catch (InvalidKeyException e) {
        System.out.println("Error: the public key is invalid.");
        return false;
      } catch (IllegalBlockSizeException e) {
        System.out.println("Error: the block size is invalid.");
        return false;
      } catch (BadPaddingException e) {
        System.out.println("Error: decrypted data is not bounded by the valid padding bytes.");
        return false;
      }

      return true;
    }
  /**
   * 입력받은 스트림을 close 여부를 전달 받아 복호화 처리를 한다.
   *
   * @param in 입력 스트림
   * @param out 출력 스트림
   * @param isStreamClose close 여부
   * @throws NoSuchAlgorithmException 암호화 알고리즘을 찾을 수 없을때 예외 처리
   * @throws InvalidKeyException 규칙에 맞지 않은 key 일때 예외 처리
   * @throws IOException 입/출력 예외 처리
   * @throws IllegalBlockSizeException 규칙에 맞지 않은 블럭사이즈 일때 예외 처리
   * @throws NoSuchPaddingException 패딩 정보를 찾을 수 없을때 예외 처리
   * @throws BadPaddingException 잘못된 패딩 일때 예외처리
   * @throws InvalidKeySpecException 규칙에 맞지 않은 keySpec 일때 예외 처리
   * @throws InvalidAlgorithmParameterException 유효하지 않은 알고리즘 파라미터 일때 예외처리
   */
  private void decrypt(InputStream in, OutputStream out, boolean isStreamClose)
      throws NoSuchAlgorithmException, InvalidKeyException, IOException, IllegalBlockSizeException,
          NoSuchPaddingException, BadPaddingException, InvalidKeySpecException,
          InvalidAlgorithmParameterException {
    Cipher cipher = Cipher.getInstance(jcrypto.getAlgorithm());
    if (JCryptoHelper.isNecessaryIvBytes(this.jcrypto.getAlgorithm())) {
      IvParameterSpec ivParameterSpec = new IvParameterSpec(JCryptoHelper.DEFAULT_IV_BYTES);
      cipher.init(
          Cipher.DECRYPT_MODE,
          generateKey(
              JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
              this.jcrypto.getAlgorithm(),
              this.jcrypto.getKeyBytes()),
          ivParameterSpec);
    } else {
      cipher.init(
          Cipher.DECRYPT_MODE,
          generateKey(
              JCryptoHelper.getKeyAlgorithm(this.jcrypto.getAlgorithm()),
              this.jcrypto.getAlgorithm(),
              this.jcrypto.getKeyBytes()));
    }

    byte[] buffer = new byte[2048];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
      out.write(cipher.update(buffer, 0, bytesRead));
    }

    out.write(cipher.doFinal());
    out.flush();
    if (isStreamClose) {
      in.close();
      out.close();
    }
  }
  private static void encrypt(
      Cipher cipher,
      int size,
      ByteBuffer heapIn,
      ByteBuffer heapOut,
      ByteBuffer directIn,
      ByteBuffer directOut,
      boolean output)
      throws Exception {

    ByteBuffer inBB = null;
    ByteBuffer outBB = null;

    // Set up data and encrypt to known/expected values.
    byte[] testdata = new byte[size];
    random.nextBytes(testdata);
    byte[] expected = cipher.doFinal(testdata);

    for (TestVariant tv : TestVariant.values()) {
      if (output) {
        System.out.print(" " + tv);
      }

      switch (tv) {
        case HEAP_HEAP:
          inBB = heapIn;
          outBB = heapOut;
          break;
        case HEAP_DIRECT:
          inBB = heapIn;
          outBB = directOut;
          break;
        case DIRECT_HEAP:
          inBB = directIn;
          outBB = heapOut;
          break;
        case DIRECT_DIRECT:
          inBB = directIn;
          outBB = directOut;
          break;
      }

      inBB.clear();
      outBB.clear();

      inBB.put(testdata);
      inBB.flip();

      // Process all data in one shot, but don't call doFinal() yet.
      // May store up to n-1 bytes (w/block size n) internally.
      cipher.update(inBB, outBB);
      if (inBB.hasRemaining()) {
        throw new Exception("buffer not empty");
      }

      // finish encryption and process all data buffered
      cipher.doFinal(inBB, outBB);
      outBB.flip();

      // validate output size
      if (outBB.remaining() != expected.length) {
        throw new Exception(
            "incomplete encryption output, expected "
                + expected.length
                + " bytes but was only "
                + outBB.remaining()
                + " bytes");
      }

      // validate output data
      byte[] encrypted = new byte[outBB.remaining()];
      outBB.get(encrypted);
      if (!Arrays.equals(expected, encrypted)) {
        throw new Exception("bad encryption output");
      }

      if (!Arrays.equals(cipher.doFinal(), cipher.doFinal())) {
        throw new Exception("Internal buffers still held data!");
      }
    }
  }
  public void prepare() {
    try {
      System.out.println(
          "\nalgorithm="
              + algorithm
              + ", mode="
              + mode
              + ", paddingStr="
              + paddingStr
              + ", msgSize="
              + msgSize
              + ", keySize="
              + keySize
              + ", noReinit="
              + noReinit
              + ", checkOutput="
              + checkOutput
              + ", encInputOffset="
              + encInputOffset
              + ", encOutputOffset="
              + encOutputOffset
              + ", decOutputOffset="
              + decOutputOffset
              + ", lastChunkSize="
              + lastChunkSize);

      if (encInputOffset % ALIGN != 0
          || encOutputOffset % ALIGN != 0
          || decOutputOffset % ALIGN != 0) testingMisalignment = true;

      int keyLenBytes = (keySize == 0 ? 16 : keySize / 8);
      byte keyBytes[] = new byte[keyLenBytes];
      if (keySize == 128)
        keyBytes = new byte[] {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
      else random.nextBytes(keyBytes);

      key = new SecretKeySpec(keyBytes, algorithm);
      if (threadId == 0) {
        System.out.println(
            "Algorithm: " + key.getAlgorithm() + "(" + key.getEncoded().length * 8 + "bit)");
      }

      cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
      dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");

      if (mode.equals("CBC")) {
        int ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0);
        IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]);
        cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
      } else {
        algParams = cipher.getParameters();
        cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
      }
      algParams = cipher.getParameters();
      dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
      if (threadId == 0) {
        childShowCipher();
      }

      inputLength = msgSize + encInputOffset;
      if (testingMisalignment) {
        encodeLength = cipher.getOutputSize(msgSize - lastChunkSize) + encOutputOffset;
        encodeLength += cipher.getOutputSize(lastChunkSize);
        decodeLength = dCipher.getOutputSize(encodeLength - lastChunkSize) + decOutputOffset;
        decodeLength += dCipher.getOutputSize(lastChunkSize);
      } else {
        encodeLength = cipher.getOutputSize(msgSize) + encOutputOffset;
        decodeLength = dCipher.getOutputSize(encodeLength) + decOutputOffset;
      }

      input = new byte[inputLength];
      for (int i = encInputOffset, j = 0; i < inputLength; i++, j++) {
        input[i] = (byte) (j & 0xff);
      }

      // do one encode and decode in preparation
      encode = new byte[encodeLength];
      decode = new byte[decodeLength];
      if (testingMisalignment) {
        decodeMsgSize =
            cipher.update(
                input, encInputOffset, (msgSize - lastChunkSize), encode, encOutputOffset);
        decodeMsgSize +=
            cipher.doFinal(
                input,
                (encInputOffset + msgSize - lastChunkSize),
                lastChunkSize,
                encode,
                (encOutputOffset + decodeMsgSize));

        int tempSize =
            dCipher.update(
                encode, encOutputOffset, (decodeMsgSize - lastChunkSize), decode, decOutputOffset);
        dCipher.doFinal(
            encode,
            (encOutputOffset + decodeMsgSize - lastChunkSize),
            lastChunkSize,
            decode,
            (decOutputOffset + tempSize));
      } else {
        decodeMsgSize = cipher.doFinal(input, encInputOffset, msgSize, encode, encOutputOffset);
        dCipher.doFinal(encode, encOutputOffset, decodeMsgSize, decode, decOutputOffset);
      }
      if (checkOutput) {
        expectedEncode = (byte[]) encode.clone();
        expectedDecode = (byte[]) decode.clone();
        showArray(key.getEncoded(), "key:    ");
        showArray(input, "input:  ");
        showArray(encode, "encode: ");
        showArray(decode, "decode: ");
      }
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }
  private void testGP(int size, int privateValueSize, BigInteger g, BigInteger p) throws Exception {
    DHParameterSpec elParams = new DHParameterSpec(p, g, privateValueSize);
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC");
    byte[] in = "This is a test".getBytes();

    keyGen.initialize(elParams);

    KeyPair keyPair = keyGen.generateKeyPair();
    SecureRandom rand = new SecureRandom();

    checkKeySize(privateValueSize, keyPair);

    Cipher cipher = Cipher.getInstance("ElGamal", "BC");

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    if (cipher.getOutputSize(in.length) != (size / 8) * 2) {
      fail("getOutputSize wrong on encryption");
    }

    byte[] out = cipher.doFinal(in);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    if (cipher.getOutputSize(out.length) != (size / 8) - 1) {
      fail("getOutputSize wrong on decryption");
    }

    //
    // No Padding - maximum length
    //
    byte[] modBytes = ((DHPublicKey) keyPair.getPublic()).getParams().getP().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    out = cipher.doFinal(maxInput);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    out = cipher.doFinal(out);

    if (!areEqual(out, maxInput)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(maxInput))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // encrypt/decrypt
    //

    Cipher c1 = Cipher.getInstance("ElGamal", "BC");
    Cipher c2 = Cipher.getInstance("ElGamal", "BC");

    c1.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    byte[] out1 = c1.doFinal(in);

    c2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    byte[] out2 = c2.doFinal(out1);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt test failed");
    }

    //
    // encrypt/decrypt with update
    //
    int outLen = c1.update(in, 0, 2, out1, 0);

    outLen += c1.doFinal(in, 2, in.length - 2, out1, outLen);

    outLen = c2.update(out1, 0, 2, out2, 0);

    outLen += c2.doFinal(out1, 2, out1.length - 2, out2, outLen);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt with update test failed");
    }

    //
    // public key encoding test
    //
    byte[] pubEnc = keyPair.getPublic().getEncoded();
    KeyFactory keyFac = KeyFactory.getInstance("ElGamal", "BC");
    X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
    DHPublicKey pubKey = (DHPublicKey) keyFac.generatePublic(pubX509);
    DHParameterSpec spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key encoding/decoding test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key encoding/decoding test failed on y value");
    }

    //
    // public key serialisation test
    //
    pubKey = (DHPublicKey) serializeDeserialize(keyPair.getPublic());
    spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key serialisation test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key serialisation test failed on y value");
    }

    if (!keyPair.getPublic().equals(pubKey)) {
      fail("equals test failed");
    }

    if (keyPair.getPublic().hashCode() != pubKey.hashCode()) {
      fail("hashCode test failed");
    }

    //
    // private key encoding test
    //
    byte[] privEnc = keyPair.getPrivate().getEncoded();
    PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
    DHPrivateKey privKey = (DHPrivateKey) keyFac.generatePrivate(privPKCS8);

    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key encoding/decoding test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key encoding/decoding test failed on y value");
    }

    //
    // private key serialisation test
    //
    privKey = (DHPrivateKey) serializeDeserialize(keyPair.getPrivate());
    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key serialisation test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key serialisation test failed on y value");
    }

    if (!keyPair.getPrivate().equals(privKey)) {
      fail("equals test failed");
    }

    if (keyPair.getPrivate().hashCode() != privKey.hashCode()) {
      fail("hashCode test failed");
    }

    if (!(privKey instanceof PKCS12BagAttributeCarrier)) {
      fail("private key not implementing PKCS12 attribute carrier");
    }
  }
  private void testDefault(int privateValueSize, BigInteger g, BigInteger p) throws Exception {
    DHParameterSpec elParams = new DHParameterSpec(p, g, privateValueSize);
    int size = p.bitLength();

    new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, elParams);

    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "BC");
    byte[] in = "This is a test".getBytes();

    keyGen.initialize(p.bitLength());

    KeyPair keyPair = keyGen.generateKeyPair();

    new BouncyCastleProvider().setParameter(ConfigurableProvider.DH_DEFAULT_PARAMS, elParams);

    SecureRandom rand = new SecureRandom();

    checkKeySize(privateValueSize, keyPair);

    Cipher cipher = Cipher.getInstance("ElGamal", "BC");

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    if (cipher.getOutputSize(in.length) != (size / 8) * 2) {
      fail("getOutputSize wrong on encryption");
    }

    byte[] out = cipher.doFinal(in);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    if (cipher.getOutputSize(out.length) != (size / 8) - 1) {
      fail("getOutputSize wrong on decryption");
    }

    //
    // No Padding - maximum length
    //
    byte[] modBytes = ((DHPublicKey) keyPair.getPublic()).getParams().getP().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    out = cipher.doFinal(maxInput);

    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    out = cipher.doFinal(out);

    if (!areEqual(out, maxInput)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(maxInput))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // encrypt/decrypt
    //

    Cipher c1 = Cipher.getInstance("ElGamal", "BC");
    Cipher c2 = Cipher.getInstance("ElGamal", "BC");

    c1.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), rand);

    byte[] out1 = c1.doFinal(in);

    c2.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());

    byte[] out2 = c2.doFinal(out1);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt test failed");
    }

    //
    // encrypt/decrypt with update
    //
    int outLen = c1.update(in, 0, 2, out1, 0);

    outLen += c1.doFinal(in, 2, in.length - 2, out1, outLen);

    outLen = c2.update(out1, 0, 2, out2, 0);

    outLen += c2.doFinal(out1, 2, out1.length - 2, out2, outLen);

    if (!areEqual(in, out2)) {
      fail(size + " encrypt with update test failed");
    }

    //
    // public key encoding test
    //
    byte[] pubEnc = keyPair.getPublic().getEncoded();
    KeyFactory keyFac = KeyFactory.getInstance("ElGamal", "BC");
    X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
    DHPublicKey pubKey = (DHPublicKey) keyFac.generatePublic(pubX509);
    DHParameterSpec spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key encoding/decoding test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key encoding/decoding test failed on y value");
    }

    //
    // public key serialisation test
    //
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ObjectOutputStream oOut = new ObjectOutputStream(bOut);

    oOut.writeObject(keyPair.getPublic());

    ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
    ObjectInputStream oIn = new ObjectInputStream(bIn);

    pubKey = (DHPublicKey) oIn.readObject();
    spec = pubKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit public key serialisation test failed on parameters");
    }

    if (!((DHPublicKey) keyPair.getPublic()).getY().equals(pubKey.getY())) {
      fail(size + " bit public key serialisation test failed on y value");
    }

    //
    // private key encoding test
    //
    byte[] privEnc = keyPair.getPrivate().getEncoded();
    PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
    DHPrivateKey privKey = (DHPrivateKey) keyFac.generatePrivate(privPKCS8);

    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key encoding/decoding test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key encoding/decoding test failed on y value");
    }

    //
    // private key serialisation test
    //
    bOut = new ByteArrayOutputStream();
    oOut = new ObjectOutputStream(bOut);

    oOut.writeObject(keyPair.getPrivate());

    bIn = new ByteArrayInputStream(bOut.toByteArray());
    oIn = new ObjectInputStream(bIn);

    privKey = (DHPrivateKey) oIn.readObject();
    spec = privKey.getParams();

    if (!spec.getG().equals(elParams.getG()) || !spec.getP().equals(elParams.getP())) {
      fail(size + " bit private key serialisation test failed on parameters");
    }

    if (!((DHPrivateKey) keyPair.getPrivate()).getX().equals(privKey.getX())) {
      fail(size + " bit private key serialisation test failed on y value");
    }
  }
  public void unwrap(NextFilter nextFilter, IoBuffer buf) {
    try {
      int len = buf.remaining();
      if (len == 0) throw new AuthException("Decryption failed");

      byte[] encryptedMsg = new byte[len - 6];
      byte[] msgType = new byte[2];
      byte[] seqNum = new byte[4];

      // Get cipherMsg; msgType; sequenceNum
      buf.get(encryptedMsg);
      buf.get(msgType);
      buf.get(seqNum);

      // Decrypt message - CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])})
      byte[] decryptedMsg;

      try {
        // Do CBC (chaining) across packets
        decryptedMsg = decCipher.update(encryptedMsg);

        // update() can return null
        if (decryptedMsg == null) throw new IllegalBlockSizeException("" + encryptedMsg.length);
      } catch (IllegalBlockSizeException e) {
        throw new AuthException("Illegal block sizes used with chosen cipher", e);
      }

      byte[] msgWithPadding = new byte[decryptedMsg.length - 10];
      byte[] mac = new byte[10];

      System.arraycopy(decryptedMsg, 0, msgWithPadding, 0, msgWithPadding.length);
      System.arraycopy(decryptedMsg, msgWithPadding.length, mac, 0, 10);

      int msgLength = msgWithPadding.length;
      int blockSize = decCipher.getBlockSize();

      if (blockSize > 1) {
        // get value of last octet of the byte array
        msgLength -= (int) msgWithPadding[msgWithPadding.length - 1];
        if (msgLength < 0)
          //  Discard message and do not increment sequence number
          throw new AuthException("Decryption failed");
      }

      byte[] msg = new byte[msgLength];
      System.arraycopy(msgWithPadding, 0, msg, 0, msgLength);

      // Re-calculate MAC to ensure integrity
      byte[] expectedMac = AuthDigestMD5IoFilter.computeMACBlock(session, msg, true);

      byte[] fullMac = new byte[16];
      System.arraycopy(mac, 0, fullMac, 0, 10);
      System.arraycopy(msgType, 0, fullMac, 10, 2);
      System.arraycopy(seqNum, 0, fullMac, 12, 4);

      if (isValidMAC(fullMac, expectedMac)) {
        IoBuffer out = IoBuffer.allocate(msgLength + LINE_TERMINATOR.length);
        out.put(msg);
        out.put(LINE_TERMINATOR);
        out.flip();

        nextFilter.messageReceived(session, out);
      }
    } catch (Exception ex) {
      log.debug(ex.getMessage());
      nextFilter.messageReceived(session, "\r\n");
    }

    if (session instanceof AbstractIoSession)
      ((AbstractIoSession) session).increaseReadMessages(System.currentTimeMillis());
  }
Beispiel #27
0
  private void testException(String name) {
    try {
      byte[] key128 = {
        (byte) 128, (byte) 131, (byte) 133, (byte) 134,
        (byte) 137, (byte) 138, (byte) 140, (byte) 143,
        (byte) 128, (byte) 131, (byte) 133, (byte) 134,
        (byte) 137, (byte) 138, (byte) 140, (byte) 143
      };

      byte[] key256 = {
        (byte) 128, (byte) 131, (byte) 133, (byte) 134,
        (byte) 137, (byte) 138, (byte) 140, (byte) 143,
        (byte) 128, (byte) 131, (byte) 133, (byte) 134,
        (byte) 137, (byte) 138, (byte) 140, (byte) 143,
        (byte) 128, (byte) 131, (byte) 133, (byte) 134,
        (byte) 137, (byte) 138, (byte) 140, (byte) 143,
        (byte) 128, (byte) 131, (byte) 133, (byte) 134,
        (byte) 137, (byte) 138, (byte) 140, (byte) 143
      };

      byte[] keyBytes;
      if (name.equals("HC256")) {
        keyBytes = key256;
      } else {
        keyBytes = key128;
      }

      SecretKeySpec cipherKey = new SecretKeySpec(keyBytes, name);
      Cipher ecipher = Cipher.getInstance(name, "BC");
      ecipher.init(Cipher.ENCRYPT_MODE, cipherKey);

      byte[] cipherText = new byte[0];
      try {
        // According specification Method engineUpdate(byte[] input,
        // int inputOffset, int inputLen, byte[] output, int
        // outputOffset)
        // throws ShortBufferException - if the given output buffer is
        // too
        // small to hold the result
        ecipher.update(new byte[20], 0, 20, cipherText);

        fail("failed exception test - no ShortBufferException thrown");
      } catch (ShortBufferException e) {
        // ignore
      }

      try {
        Cipher c = Cipher.getInstance(name, "BC");

        Key k =
            new PublicKey() {

              public String getAlgorithm() {
                return "STUB";
              }

              public String getFormat() {
                return null;
              }

              public byte[] getEncoded() {
                return null;
              }
            };

        c.init(Cipher.ENCRYPT_MODE, k);

        fail("failed exception test - no InvalidKeyException thrown for public key");
      } catch (InvalidKeyException e) {
        // okay
      }

      try {
        Cipher c = Cipher.getInstance(name, "BC");

        Key k =
            new PrivateKey() {

              public String getAlgorithm() {
                return "STUB";
              }

              public String getFormat() {
                return null;
              }

              public byte[] getEncoded() {
                return null;
              }
            };

        c.init(Cipher.DECRYPT_MODE, k);

        fail("failed exception test - no InvalidKeyException thrown for private key");
      } catch (InvalidKeyException e) {
        // okay
      }
    } catch (Exception e) {
      fail("unexpected exception.", e);
    }
  }
Beispiel #28
0
 public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception {
   cipher.update(foo, s1, len, bar, s2);
 }
Beispiel #29
0
  public void performTest() throws Exception {
    KeyFactory fact;
    byte[] input =
        new byte[] {
          (byte) 0x54,
          (byte) 0x85,
          (byte) 0x9b,
          (byte) 0x34,
          (byte) 0x2c,
          (byte) 0x49,
          (byte) 0xea,
          (byte) 0x2a
        };
    byte[][] output =
        new byte[][] {
          Hex.decode(
              "8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"),
          Hex.decode(
              "2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"),
          Hex.decode(
              "0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"),
          Hex.decode(
              "1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"),
          Hex.decode(
              "4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"),
          Hex.decode(
              "06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"),
          Hex.decode(
              "135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"),
          Hex.decode(
              "03c05add1e030178c352face07cafc9447c8f369b8f95125c0d311c16b6da48ca2067104cce6cd21ae7b163cd18ffc13001aecebdc2eb02b9e92681f84033a98"),
          Hex.decode(
              "00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c")
        };
    SecureRandom rand = new FixedSecureRandom();

    fact = KeyFactory.getInstance("RSA", "BC");

    PrivateKey privKey = fact.generatePrivate(privKeySpec);
    PublicKey pubKey = fact.generatePublic(pubKeySpec);

    PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec);
    PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec);

    //
    // key without CRT coefficients
    //
    PrivateKeyInfo keyInfo = PrivateKeyInfo.getInstance(privKey.getEncoded());
    BigInteger zero = BigInteger.valueOf(0);
    PKCS8EncodedKeySpec noCrtSpec =
        new PKCS8EncodedKeySpec(
            new PrivateKeyInfo(
                    keyInfo.getPrivateKeyAlgorithm(),
                    new org.mightyfish.asn1.pkcs.RSAPrivateKey(
                        privKeySpec.getModulus(),
                        privKeySpec.getPublicExponent(),
                        privKeySpec.getPrivateExponent(),
                        zero,
                        zero,
                        zero,
                        zero,
                        zero))
                .getEncoded());

    PrivateKey noCrtKey = fact.generatePrivate(noCrtSpec);
    if (noCrtKey instanceof RSAPrivateCrtKey) {
      fail("private key without CRT coefficients returned as CRT key");
    }

    //
    // No Padding
    //
    Cipher c = Cipher.getInstance("RSA", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    byte[] out = c.doFinal(input);

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // No Padding - incremental
    //
    c = Cipher.getInstance("RSA", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    c.update(input);

    out = c.doFinal();

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // No Padding - incremental - explicit use of NONE in mode.
    //
    c = Cipher.getInstance("RSA/NONE/NoPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    c.update(input);

    out = c.doFinal();

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // No Padding - maximum length
    //
    c = Cipher.getInstance("RSA", "BC");

    byte[] modBytes = ((RSAPublicKey) pubKey).getModulus().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(maxInput);

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, maxInput)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(maxInput))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // PKCS1 V 1.5
    //
    c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[1])) {
      fail(
          "PKCS1 test failed on encrypt expected "
              + new String(Hex.encode(output[1]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "PKCS1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // PKCS1 V 1.5 - NONE
    //
    c = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[1])) {
      fail(
          "PKCS1 test failed on encrypt expected "
              + new String(Hex.encode(output[1]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "PKCS1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // OAEP - SHA1
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[2])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    AlgorithmParameters oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-1 parameters");
    }

    //
    // OAEP - SHA224
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA224AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[3])) {
      fail(
          "OAEP SHA-224 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-224 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-224 parameters");
    }

    //
    // OAEP - SHA 256
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[4])) {
      fail(
          "OAEP SHA-256 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-256 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-256 parameters");
    }

    //
    // OAEP - SHA 384
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA384AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[5])) {
      fail(
          "OAEP SHA-384 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-384 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-384 parameters");
    }

    //
    // OAEP - MD5
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithMD5AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[6])) {
      fail(
          "OAEP MD5 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP MD5 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default md5 parameters");
    }

    //
    // OAEP - SHA1 with default parameters
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, OAEPParameterSpec.DEFAULT, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[2])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(oaepP.getEncoded(), new byte[] {0x30, 0x00})) {
      fail("OAEP test failed default parameters");
    }

    //
    // OAEP - SHA1 with specified string
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(
        Cipher.ENCRYPT_MODE,
        pubKey,
        new OAEPParameterSpec(
            "SHA1",
            "MGF1",
            new MGF1ParameterSpec("SHA1"),
            new PSource.PSpecified(new byte[] {1, 2, 3, 4, 5})),
        rand);

    out = c.doFinal(input);

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified,
                    new DEROctetString(new byte[] {1, 2, 3, 4, 5})))
            .getEncoded())) {
      fail("OAEP test failed changed sha-1 parameters");
    }

    if (!areEqual(out, output[7])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey, oaepP);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // ISO9796-1
    //
    byte[] isoInput =
        Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210");
    PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec);
    PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec);

    c = Cipher.getInstance("RSA/NONE/ISO9796-1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, isoPrivKey);

    out = c.doFinal(isoInput);

    if (!areEqual(out, output[8])) {
      fail(
          "ISO9796-1 test failed on encrypt expected "
              + new String(Hex.encode(output[3]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, isoPubKey);

    out = c.doFinal(out);

    if (!areEqual(out, isoInput)) {
      fail(
          "ISO9796-1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    //
    // generation with parameters test.
    //
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");

    //
    // 768 bit RSA with e = 2^16-1
    //
    keyPairGen.initialize(
        new RSAKeyGenParameterSpec(768, BigInteger.valueOf(65537)), new SecureRandom());

    KeyPair kp = keyPairGen.generateKeyPair();

    pubKey = kp.getPublic();
    privKey = kp.getPrivate();

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "key generation test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // comparison check
    //
    KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC");

    RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) keyFact.translateKey(privKey);

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    crtKey =
        (RSAPrivateCrtKey) keyFact.generatePrivate(new PKCS8EncodedKeySpec(privKey.getEncoded()));

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    crtKey = (RSAPrivateCrtKey) serializeDeserialize(privKey);

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    if (privKey.hashCode() != crtKey.hashCode()) {
      fail("private key hashCode check failed");
    }

    RSAPublicKey copyKey = (RSAPublicKey) keyFact.translateKey(pubKey);

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    copyKey = (RSAPublicKey) keyFact.generatePublic(new X509EncodedKeySpec(pubKey.getEncoded()));

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    copyKey = (RSAPublicKey) serializeDeserialize(pubKey);

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    if (pubKey.hashCode() != copyKey.hashCode()) {
      fail("public key hashCode check failed");
    }

    //
    // test an OAEP key
    //
    SubjectPublicKeyInfo oaepKey =
        new SubjectPublicKeyInfo(
            new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, new RSAESOAEPparams()),
            SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()).parsePublicKey());

    copyKey =
        (RSAPublicKey)
            serializeDeserialize(
                keyFact.generatePublic(new X509EncodedKeySpec(oaepKey.getEncoded())));

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    if (pubKey.hashCode() != copyKey.hashCode()) {
      fail("public key hashCode check failed");
    }

    if (!Arrays.areEqual(copyKey.getEncoded(), oaepKey.getEncoded())) {
      fail("encoding does not match");
    }

    oaepCompatibilityTest("SHA-1", priv2048Key, pub2048Key);
    // TODO: oaepCompatibilityTest("SHA-224", priv2048Key, pub2048Key);      commented out as fails
    // in JDK 1.7
    oaepCompatibilityTest("SHA-256", priv2048Key, pub2048Key);
    oaepCompatibilityTest("SHA-384", priv2048Key, pub2048Key);
    oaepCompatibilityTest("SHA-512", priv2048Key, pub2048Key);

    SecureRandom random = new SecureRandom();
    rawModeTest("SHA1withRSA", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random);
    rawModeTest("MD5withRSA", PKCSObjectIdentifiers.md5, priv2048Key, pub2048Key, random);
    rawModeTest(
        "RIPEMD128withRSA", TeleTrusTObjectIdentifiers.ripemd128, priv2048Key, pub2048Key, random);

    // init reset test
    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.update(new byte[40]);

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.update(new byte[40]);
  }
  public static Message decode(Session session, String text) {
    Logger logger = LoggerFactory.getLogger(KrakenMessageDecoder.class.getName());
    Charset utf8 = Charset.forName("utf-8");

    // remove potential control characters
    text = text.trim();
    if (text.length() == 0) return null;

    if (logger.isDebugEnabled())
      logger.debug(
          "kraken webconsole: debug websocket frame length {}, json [{}]", text.length(), text);

    if (text.equals("ping")) return null;

    // decrypt if msg is encrypted
    if (session.has("enc_key")) {
      try {
        JSONTokener tokenizer = new JSONTokener(new StringReader(text));
        JSONArray container = (JSONArray) tokenizer.nextValue();
        JSONObject header = container.getJSONObject(0);
        JSONObject body = container.getJSONObject(1);

        if (header.has("iv") && body.has("data")) {
          String data = body.getString("data");

          byte[] iv =
              ByteUtil.asArray(
                  Base64.decode(ChannelBuffers.wrappedBuffer(header.getString("iv").getBytes())));
          byte[] buf =
              ByteUtil.asArray(Base64.decode(ChannelBuffers.wrappedBuffer(data.getBytes())));
          byte[] key = ByteUtil.asByteArray(UUID.fromString(session.getString("enc_key")));
          SecretKeySpec secret = new SecretKeySpec(key, "AES");

          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
          cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
          byte[] plain = new byte[cipher.getOutputSize(buf.length)];
          int plainLength = cipher.update(buf, 0, buf.length, plain, 0);
          plainLength += cipher.doFinal(plain, plainLength);

          text = new String(plain, 0, plainLength, utf8);
          logger.trace("kraken webconsole: decrypted msg [{}]", text);
        }
      } catch (Exception e) {
        logger.error("kraken webconsole: cannot decode encrypted msg [" + text + "]", e);
      }
    }

    try {
      JSONTokener tokenizer = new JSONTokener(new StringReader(text));
      JSONArray container = (JSONArray) tokenizer.nextValue();
      JSONObject header = container.getJSONObject(0);
      JSONObject body = container.getJSONObject(1);

      Message msg = new Message();

      msg.setGuid(header.getString("guid").trim());
      msg.setType(Message.Type.valueOf(header.getString("type").trim()));
      msg.setSource(header.getString("source"));
      msg.setTarget(header.getString("target"));
      msg.setMethod(header.getString("method").trim());
      msg.setParameters(parse(body));

      return msg;
    } catch (JSONException e) {
      logger.error("kraken webconsole: invalid json => " + text, e);
    }
    return null;
  }