예제 #1
0
  private void testNullCFB() throws InvalidCipherTextException {
    BufferedBlockCipher b = new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128));
    KeyParameter kp = new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917"));

    b.init(true, new ParametersWithIV(kp, new byte[16]));

    byte[] out = new byte[b.getOutputSize(tData.length)];

    int len = b.processBytes(tData, 0, tData.length, out, 0);

    len += b.doFinal(out, len);

    if (!areEqual(outCFB1, out)) {
      fail("no match on first nullCFB check");
    }

    b.init(true, new ParametersWithIV(null, Hex.decode("000102030405060708090a0b0c0d0e0f")));

    len = b.processBytes(tData, 0, tData.length, out, 0);

    len += b.doFinal(out, len);

    if (!areEqual(outCFB2, out)) {
      fail("no match on second nullCFB check");
    }
  }
예제 #2
0
  private static PrivateKey derivePrivateKeyPBES2(
      org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn,
      AlgorithmIdentifier algId,
      char[] password)
      throws GeneralSecurityException, InvalidCipherTextException {
    PBES2Parameters pbeParams = new PBES2Parameters((ASN1Sequence) algId.getParameters());
    CipherParameters cipherParams = extractPBES2CipherParams(password, pbeParams);

    EncryptionScheme scheme = pbeParams.getEncryptionScheme();
    BufferedBlockCipher cipher;
    if (scheme.getAlgorithm().equals(PKCSObjectIdentifiers.RC2_CBC)) {
      RC2CBCParameter rc2Params = new RC2CBCParameter((ASN1Sequence) scheme.getObject());
      byte[] iv = rc2Params.getIV();
      CipherParameters param = new ParametersWithIV(cipherParams, iv);
      cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RC2Engine()));
      cipher.init(false, param);
    } else {
      byte[] iv = ((ASN1OctetString) scheme.getObject()).getOctets();
      CipherParameters param = new ParametersWithIV(cipherParams, iv);
      cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
      cipher.init(false, param);
    }

    byte[] data = eIn.getEncryptedData();
    byte[] out = new byte[cipher.getOutputSize(data.length)];
    int len = cipher.processBytes(data, 0, data.length, out, 0);
    len += cipher.doFinal(out, len);
    byte[] pkcs8 = new byte[len];
    System.arraycopy(out, 0, pkcs8, 0, len);
    KeyFactory fact = KeyFactory.getInstance("RSA"); // It seems to work for both RSA and DSA.
    return fact.generatePrivate(new PKCS8EncodedKeySpec(pkcs8));
  }
 @Override
 protected void write(byte[] buf, int length) {
   System.out.println("Writing: " + length);
   if (stored > 0) {
     throw new IllegalStateException(
         "Stored data must be completely read before writing more data");
   }
   stored = cipher.processBytes(buf, 0, length, processed, 0);
   System.out.println("Stored: " + stored);
   position = 0;
 }
  public boolean EncryptMsg(String TobeEncrypted, String CertFile) throws Exception {
    reset();

    byte[] plain = TobeEncrypted.getBytes(encoding);
    byte[] iv = "12345678".getBytes(encoding);

    RSAKeyParameters rsaParams = null;
    rsaParams = getRSAKeyParameters(CertFile);

    BigInteger mod = rsaParams.getModulus();

    int keylen = mod.bitLength() / 8;
    if (plain.length > keylen - 11) {
      SecureRandom securerandom = new SecureRandom();
      DESedeKeyGenerator desedeKeyGenerator = new DESedeKeyGenerator();
      desedeKeyGenerator.init(new KeyGenerationParameters(securerandom, 192));
      byte[] key = desedeKeyGenerator.generateKey();
      if (key.length != 24) {
        throw new Exception("密钥长度不为24,加密失败");
      }

      byte[] encryptedPlain = new byte[plain.length];
      DESedeEngine desede = new DESedeEngine();
      BufferedBlockCipher bufferedBlockCipher =
          new BufferedBlockCipher(new OFBBlockCipher(desede, 8 * desede.getBlockSize()));
      CipherParameters desedeParams = new ParametersWithIV(new DESedeParameters(key), iv);
      bufferedBlockCipher.init(true, desedeParams);
      int outOff = bufferedBlockCipher.processBytes(plain, 0, plain.length, encryptedPlain, 0);
      bufferedBlockCipher.doFinal(encryptedPlain, outOff);
      byte[] encryptedKey = (byte[]) null;
      AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine());
      rsa.init(true, rsaParams);
      encryptedKey = rsa.processBlock(key, 0, key.length);
      this.lastResult =
          new String(Hex.encode(iv))
              + new String(Hex.encode(encryptedKey))
              + new String(Hex.encode(encryptedPlain));
    } else {
      byte[] encrypted = (byte[]) null;
      AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine());
      rsa.init(true, rsaParams);
      encrypted = rsa.processBlock(plain, 0, plain.length);
      this.lastResult = new String(Hex.encode(encrypted));
    }

    return true;
  }
예제 #5
0
 private SecretKey generateSecretKey(byte[] keyBytes, int nBits) throws Exception {
   try {
     SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
     /* AES/ECB/NoPadding */
     org.bouncycastle.crypto.BufferedBlockCipher cipher =
         new org.bouncycastle.crypto.BufferedBlockCipher(
             new org.bouncycastle.crypto.engines.AESEngine());
     cipher.init(true, new org.bouncycastle.crypto.params.KeyParameter(secretKey.getEncoded()));
     keyBytes = new byte[cipher.getOutputSize(secretKey.getEncoded().length)];
     int decLength =
         cipher.processBytes(
             secretKey.getEncoded(), 0, secretKey.getEncoded().length, keyBytes, 0);
     cipher.doFinal(keyBytes, decLength);
   } catch (Throwable e) {
     return null;
   }
   System.arraycopy(keyBytes, 0, keyBytes, nBits / 2, nBits / 2);
   return new SecretKeySpec(keyBytes, "AES");
 }
예제 #6
0
 private String decrypt(String cipherText, String key, int nBits) throws Exception {
   if (!(nBits == 128 || nBits == 192 || nBits == 256)) {
     return "Error: Must be a key mode of either 128, 192, 256 bits";
   }
   if (cipherText == null || key == null) {
     return "Error: cipher and/or key equals null";
   }
   byte[] decrypted;
   nBits = nBits / 8;
   byte[] data = Base64.decode(cipherText.toCharArray());
   /*
    * CHECK: we should always use getBytes("UTF-8") or with wanted charset, never system charset!
    */
   byte[] k = Arrays.copyOf(key.getBytes(), nBits);
   /* AES/CTR/NoPadding (SIC == CTR) */
   org.bouncycastle.crypto.BufferedBlockCipher cipher =
       new org.bouncycastle.crypto.BufferedBlockCipher(
           new org.bouncycastle.crypto.modes.SICBlockCipher(
               new org.bouncycastle.crypto.engines.AESEngine()));
   cipher.reset();
   SecretKey secretKey = generateSecretKey(k, nBits);
   byte[] nonceBytes = Arrays.copyOf(Arrays.copyOf(data, 8), nBits / 2);
   IvParameterSpec nonce = new IvParameterSpec(nonceBytes);
   /* true == encrypt; false == decrypt */
   cipher.init(
       true,
       new org.bouncycastle.crypto.params.ParametersWithIV(
           new org.bouncycastle.crypto.params.KeyParameter(secretKey.getEncoded()),
           nonce.getIV()));
   decrypted = new byte[cipher.getOutputSize(data.length - 8)];
   int decLength = cipher.processBytes(data, 8, data.length - 8, decrypted, 0);
   cipher.doFinal(decrypted, decLength);
   /*
    * CHECK: we should always use new String (bytes,charset) to avoid issues with system charset and utf-8
    */
   return new String(decrypted);
 }
예제 #7
0
  static byte[] crypt(
      boolean encrypt,
      Provider provider,
      byte[] bytes,
      char[] password,
      String dekAlgName,
      byte[] iv)
      throws IOException {
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    String alg;
    String blockMode = "CBC";
    String padding = "PKCS5Padding";
    Key sKey;

    // Figure out block mode and padding.
    if (dekAlgName.endsWith("-CFB")) {
      blockMode = "CFB";
      padding = "NoPadding";
    }
    if (dekAlgName.endsWith("-ECB")
        || "DES-EDE".equals(dekAlgName)
        || "DES-EDE3".equals(dekAlgName)) {
      // ECB is actually the default (though seldom used) when OpenSSL
      // uses DES-EDE (des2) or DES-EDE3 (des3).
      blockMode = "ECB";
      paramSpec = null;
    }
    if (dekAlgName.endsWith("-OFB")) {
      blockMode = "OFB";
      padding = "NoPadding";
    }

    // Figure out algorithm and key size.
    if (dekAlgName.startsWith("DES-EDE")) {
      alg = "DESede";
      // "DES-EDE" is actually des2 in OpenSSL-speak!
      // "DES-EDE3" is des3.
      boolean des2 = !dekAlgName.startsWith("DES-EDE3");
      sKey = getKey(password, alg, 24, iv, des2);
    } else if (dekAlgName.startsWith("DES-")) {
      alg = "DES";
      sKey = getKey(password, alg, 8, iv);
    } else if (dekAlgName.startsWith("BF-")) {
      alg = "Blowfish";
      sKey = getKey(password, alg, 16, iv);
    } else if (dekAlgName.startsWith("RC2-")) {
      alg = "RC2";
      int keyBits = 128;
      if (dekAlgName.startsWith("RC2-40-")) {
        keyBits = 40;
      } else if (dekAlgName.startsWith("RC2-64-")) {
        keyBits = 64;
      }
      sKey = getKey(password, alg, keyBits / 8, iv);
      if (paramSpec == null) // ECB block mode
      {
        paramSpec = new RC2ParameterSpec(keyBits);
      } else {
        paramSpec = new RC2ParameterSpec(keyBits, iv);
      }
    } else if (dekAlgName.startsWith("AES-")) {
      alg = "AES";
      byte[] salt = iv;
      if (salt.length > 8) {
        salt = new byte[8];
        System.arraycopy(iv, 0, salt, 0, 8);
      }

      int keyBits;
      if (dekAlgName.startsWith("AES-128-")) {
        keyBits = 128;
      } else if (dekAlgName.startsWith("AES-192-")) {
        keyBits = 192;
      } else if (dekAlgName.startsWith("AES-256-")) {
        keyBits = 256;
      } else {
        throw new EncryptionException("unknown AES encryption with private key");
      }
      sKey = getKey(password, "AES", keyBits / 8, salt);
    } else {
      throw new EncryptionException("unknown encryption with private key");
    }

    String transformation = alg + "/" + blockMode + "/" + padding;

    // Instantiate manually the AES Engine without the Javax.Security.Provider
    // in oder to avoid securityException "JCE cannot authenticate the provider"
    try {
      // Here alg = AES
      AESEngine engine = new AESEngine();

      // use the right block mode
      BufferedBlockCipher bbc = null;
      BlockCipher bc = null;
      if ("CBC".equals(blockMode)) {
        bc = new CBCBlockCipher(engine);

      } else if ("OFB".equals(blockMode)) {
        bc = new OFBBlockCipher(engine, 128);
      } else {
        throw new EncryptionException("unknown encryption block mode " + blockMode);
      }

      // add the padding
      if ("NoPadding".equals(padding)) {
        bbc = new BufferedBlockCipher(bc);
      } else if ("PKCS5Padding".equals(padding) || "PKCS7Padding".equals(padding)) {
        // PKCS7Padding implementation supports both PKCS5 and PKCS7 padding
        bbc = new PaddedBufferedBlockCipher(bc, new PKCS7Padding());
      } else {
        throw new EncryptionException("unknown encryption padding " + padding);
      }

      KeyParameter kp = new KeyParameter(sKey.getEncoded());

      bbc.init(encrypt, new ParametersWithIV(kp, iv));

      byte[] out = new byte[bbc.getOutputSize(bytes.length)];

      int len = bbc.processBytes(bytes, 0, bytes.length, out, 0);

      bbc.doFinal(out, len);

      return out;
    } catch (Exception e) {
      throw new EncryptionException("exception using cipher - please check password and data.", e);
    }
  }