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"); } }
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; }
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"); }
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); }
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); } }