/* * Initial IV client to server: HASH (K || H || "A" || session_id) Initial * IV server to client: HASH (K || H || "B" || session_id) Encryption key * client to server: HASH (K || H || "C" || session_id) Encryption key * server to client: HASH (K || H || "D" || session_id) Integrity key client * to server: HASH (K || H || "E" || session_id) Integrity key server to * client: HASH (K || H || "F" || session_id) */ public void init( String encryptionAlgorithm, String cipherAlgorithm, int keyLength, String macAlgorithm, byte[] K, byte[] H, byte[] sessionId) throws GeneralSecurityException { MessageDigest sha = MessageDigest.getInstance("SHA-1"); sha.reset(); sha.update( new SshPacketBuilder().writeMpInt(K).append(H).writeByte('A').append(sessionId).finish()); byte[] iv = sha.digest(); sha.reset(); sha.update( new SshPacketBuilder().writeMpInt(K).append(H).writeByte('C').append(sessionId).finish()); byte[] cipherKey = sha.digest(); try { cipher = Cipher.getInstance(encryptionAlgorithm + "/" + cipherAlgorithm + "/NoPadding"); iv = CipherUtils.expandKey(K, H, iv, sha, cipher.getBlockSize()); cipherKey = CipherUtils.expandKey(K, H, cipherKey, sha, keyLength); iv = CipherUtils.shrinkKey(iv, cipher.getBlockSize()); cipherKey = CipherUtils.shrinkKey(cipherKey, keyLength); cipher.init( Cipher.ENCRYPT_MODE, new SecretKeySpec(cipherKey, encryptionAlgorithm), new IvParameterSpec(iv)); sha.reset(); sha.update( new SshPacketBuilder().writeMpInt(K).append(H).writeByte('E').append(sessionId).finish()); byte[] macKey = sha.digest(); mac = Mac.getInstance(macAlgorithm); macKey = CipherUtils.expandKey(K, H, macKey, sha, mac.getMacLength()); macKey = CipherUtils.shrinkKey(macKey, mac.getMacLength()); mac.init(new SecretKeySpec(macKey, macAlgorithm)); } catch (GeneralSecurityException e) { cipher = null; mac = null; throw e; } }
@Override public void setup() { try { algo = javax.crypto.Cipher.getInstance("AES/CFB8/NoPadding"); java.security.Key key = new SecretKeySpec(publicKey, 0, 16, "AES"); algo.init(javax.crypto.Cipher.ENCRYPT_MODE, key); } catch (Exception e) { System.out.println(e); } inAlgoBuffer = new byte[algo.getBlockSize()]; // always 0x00's outAlgoBufferIx = algo.getOutputSize(algo.getBlockSize()); outAlgoBuffer = new byte[outAlgoBufferIx]; // output of encryption }
private static void writePemEncrypted( BufferedWriter out, String pemHeader, byte[] encoding, CipherSpec cipher, char[] passwd) throws IOException { Cipher c = cipher.getCipher(); byte[] iv = new byte[c.getBlockSize()]; random.nextBytes(iv); byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(cipher.getKeyLenInBits()); SecretKey secretKey = new SecretKeySpec( param.getKey(), org.jruby.ext.openssl.Cipher.Algorithm.getAlgorithmBase(c)); byte[] encData = null; try { c.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv)); encData = c.doFinal(encoding); } catch (GeneralSecurityException gse) { throw new IOException("exception using cipher: " + gse.toString()); } out.write(BEF_G + pemHeader + AFT); out.newLine(); out.write("Proc-Type: 4,ENCRYPTED"); out.newLine(); out.write("DEK-Info: " + cipher.getOsslName() + ","); writeHexEncoded(out, iv); out.newLine(); out.newLine(); writeEncoded(out, encData); out.write(BEF_E + pemHeader + AFT); out.flush(); }
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; }
PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { try { SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); final Cipher c = createStreamCipher(encAlgorithm, withIntegrityPacket); if (withIntegrityPacket) { byte[] iv = new byte[c.getBlockSize()]; c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); } else { c.init(Cipher.DECRYPT_MODE, secretKey); } return new PGPDataDecryptor() { public InputStream getInputStream(InputStream in) { return new CipherInputStream(in, c); } public int getBlockSize() { return c.getBlockSize(); } public PGPDigestCalculator getIntegrityCalculator() { return new SHA1PGPDigestCalculator(); } }; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } }
/** signature with a "forged signature" (sig block not at end of plain text) */ private void testBadSig(PrivateKey priv, PublicKey pub) throws Exception { MessageDigest sha1 = MessageDigest.getInstance("SHA1", "BC"); Cipher signer = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); signer.init(Cipher.ENCRYPT_MODE, priv); byte[] block = new byte[signer.getBlockSize()]; sha1.update((byte) 0); byte[] sigHeader = Hex.decode("3021300906052b0e03021a05000414"); System.arraycopy(sigHeader, 0, block, 0, sigHeader.length); byte[] dig = sha1.digest(); System.arraycopy(dig, 0, block, sigHeader.length, dig.length); System.arraycopy(sigHeader, 0, block, sigHeader.length + dig.length, sigHeader.length); byte[] sig = signer.doFinal(block); Signature verifier = Signature.getInstance("SHA1WithRSA", "BC"); verifier.initVerify(pub); verifier.update((byte) 0); if (verifier.verify(sig)) { fail("bad signature passed"); } }
public static byte[] encryptDataBytes(PublicKey publicKey, byte[] data) { try { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider()); cipher.init(1, publicKey); int blockSize = cipher.getBlockSize(); int outputSize = cipher.getOutputSize(data.length); int leavedSize = data.length % blockSize; int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize; byte[] raw = new byte[outputSize * blocksSize]; int i = 0; while (data.length - i * blockSize > 0) { if (data.length - i * blockSize > blockSize) cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize); else { cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize); } i++; } return raw; } catch (Exception e) { logger.error(e.getMessage()); return null; } }
/** * 解密 * * @param key 解密的密钥 * @param raw 已经加密的数据 * @return 解密后的明文 * @throws Exception */ public static byte[] decrypt(Key key, byte[] raw) throws Exception { try { Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, key); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (raw.length - j * blockSize > 0) { bout.write(cipher.doFinal(raw, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { throw new Exception(e.getMessage()); } }
public static String decodeAES(String base64CipherTxt, String pwd, final int keySizeBits) { final Charset ASCII = Charset.forName("ASCII"); final int INDEX_KEY = 0; final int INDEX_IV = 1; final int ITERATIONS = 1; final int SALT_OFFSET = 8; final int SALT_SIZE = 8; final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE; try { byte[] headerSaltAndCipherText = Base64.base64ToByteArray(base64CipherTxt); // --- extract salt & encrypted --- // header is "Salted__", ASCII encoded, if salt is being used (the default) byte[] salt = Arrays.copyOfRange(headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE); byte[] encrypted = Arrays.copyOfRange( headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length); // --- specify cipher and digest for evpBytesTokey method --- Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding"); MessageDigest md5 = MessageDigest.getInstance("MD5"); // --- create key and IV --- // the IV is useless, OpenSSL might as well have use zero's final byte[][] keyAndIV = evpBytesTokey( keySizeBits / Byte.SIZE, aesCBC.getBlockSize(), md5, salt, pwd.getBytes(ASCII), ITERATIONS); SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES"); IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]); // --- initialize cipher instance and decrypt --- aesCBC.init(Cipher.DECRYPT_MODE, key, iv); byte[] decrypted = aesCBC.doFinal(encrypted); return new String(decrypted, ASCII); } catch (BadPaddingException e) { // AKA "something went wrong" throw new IllegalStateException( "Bad password, algorithm, mode or padding;" + " no salt, wrong number of iterations or corrupted ciphertext.", e); } catch (IllegalBlockSizeException e) { throw new IllegalStateException("Bad algorithm, mode or corrupted (resized) ciphertext.", e); } catch (GeneralSecurityException e) { throw new IllegalStateException(e); } }
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); // Cipher cipher = Cipher.getInstance("AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init( Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] decrypted = cipher.doFinal(encrypted); return decrypted; }
private Cipher getDecryptingCipher(SecretKeySpec key, byte[] encryptedBody) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException { // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec(encryptedBody, 0, decryptingCipher.getBlockSize()); decryptingCipher.init(Cipher.DECRYPT_MODE, key, iv); return decryptingCipher; }
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM); // Cipher cipher = Cipher.getInstance("AES"); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); cipher.init( Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] encrypted = cipher.doFinal(clear); return encrypted; }
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); } }
/** * Calculates the length of the encrypted file given the original plaintext file length and the * cipher that will be used for encryption. * * @return The size of the encrypted file in bytes, or -1 if no content length has been set yet. * @deprecated no longer used and will be removed in the future */ @Deprecated private static long calculateCryptoContentLength( Cipher symmetricCipher, PutObjectRequest request, ObjectMetadata metadata) { long plaintextLength = getUnencryptedContentLength(request, metadata); // If we don't know the unencrypted size, then report -1 if (plaintextLength < 0) return -1; long cipherBlockSize = symmetricCipher.getBlockSize(); long offset = cipherBlockSize - (plaintextLength % cipherBlockSize); return plaintextLength + offset; }
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); }
/** * Takes ciphertexts and decrypts it * * @param data correctly padded data * @return * @throws CryptoException */ public byte[] decrypt(byte[] data) throws CryptoException { try { byte[] plaintext; if (useExplicitIv) { decryptIv = new IvParameterSpec(Arrays.copyOf(data, decryptCipher.getBlockSize())); } if (tlsContext.getMyConnectionEnd() == ConnectionEnd.CLIENT) { decryptCipher.init( Cipher.DECRYPT_MODE, new SecretKeySpec(serverWriteKey, bulkCipherAlg.getJavaName()), decryptIv); } else { decryptCipher.init( Cipher.DECRYPT_MODE, new SecretKeySpec(clientWriteKey, bulkCipherAlg.getJavaName()), decryptIv); } if (useExplicitIv) { plaintext = decryptCipher.doFinal( Arrays.copyOfRange(data, decryptCipher.getBlockSize(), data.length)); } else { plaintext = decryptCipher.doFinal(data); decryptIv = new IvParameterSpec( Arrays.copyOfRange(data, data.length - decryptCipher.getBlockSize(), data.length)); } return plaintext; } catch (BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException | UnsupportedOperationException ex) { throw new CryptoException(ex); } }
private void testTampering(boolean aeadAvailable) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC"); final SecretKeySpec key = new SecretKeySpec(new byte[eax.getBlockSize()], eax.getAlgorithm()); final IvParameterSpec iv = new IvParameterSpec(new byte[eax.getBlockSize()]); eax.init(Cipher.ENCRYPT_MODE, key, iv); byte[] ciphertext = eax.doFinal(new byte[100]); ciphertext[0] = (byte) (ciphertext[0] + 1); // Tamper try { eax.init(Cipher.DECRYPT_MODE, key, iv); eax.doFinal(ciphertext); fail("Tampered ciphertext should be invalid"); } catch (BadPaddingException e) { if (aeadAvailable) { if (!e.getClass().getName().equals("javax.crypto.AEADBadTagException")) { fail("Tampered AEAD ciphertext should fail with AEADBadTagException when available."); } } } }
/** @deprecated no longer used and will be removed in the future */ @Deprecated public static long calculateCryptoContentLength( Cipher symmetricCipher, UploadPartRequest request) { long plaintextLength; if (request.getFile() != null) { if (request.getPartSize() > 0) plaintextLength = request.getPartSize(); else plaintextLength = request.getFile().length(); } else if (request.getInputStream() != null) { plaintextLength = request.getPartSize(); } else { return -1; } long cipherBlockSize = symmetricCipher.getBlockSize(); long offset = cipherBlockSize - (plaintextLength % cipherBlockSize); return plaintextLength + offset; }
@Override public String decrypt(ZWEncryptedData encryptedData) throws ZWKeyCrypterException { try { String encrypted = encryptedData.getEncryptedData(); Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM); int ivLength = decryptionCipher.getBlockSize(); String ivHex = encrypted.substring(0, ivLength * 2); String encryptedHex = encrypted.substring(ivLength * 2); IvParameterSpec ivspec = new IvParameterSpec(ZiftrUtils.hexStringToBytes(ivHex)); decryptionCipher.init(Cipher.DECRYPT_MODE, this.secretKey, ivspec); byte[] decryptedText = decryptionCipher.doFinal(ZiftrUtils.hexStringToBytes(encryptedHex)); String decrypted = new String(decryptedText, "UTF-8"); return decrypted; } catch (Exception e) { throw new ZWKeyCrypterException("Unable to decrypt", e); } }
/** * 加密 * * @param key 加密的密钥 * @param data 待加密的明文数据 * @return 加密后的数据 * @throws Exception */ public static byte[] encrypt(Key key, byte[] data) throws Exception { try { Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, key); int blockSize = cipher.getBlockSize(); // 获得加密块大小,如:加密前数据为128个byte,而key_size=1024 // 加密块大小为127 // byte,加密后为128个byte;因此共有2个加密块,第一个127 // byte第二个为1个byte int outputSize = cipher.getOutputSize(data.length); // 获得加密块加密后块大小 int leavedSize = data.length % blockSize; int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize; byte[] raw = new byte[outputSize * blocksSize]; int i = 0; while (data.length - i * blockSize > 0) { if (data.length - i * blockSize > blockSize) cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize); else cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize); // 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。 i++; } return raw; } catch (Exception e) { throw new Exception(e.getMessage()); } }
/** * 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 ZWEncryptedData encrypt(String clearText) throws ZWKeyCrypterException { try { Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM); byte[] iv = generateIv(encryptionCipher.getBlockSize()); String ivHex = ZiftrUtils.bytesToHexString(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv); encryptionCipher.init(Cipher.ENCRYPT_MODE, this.secretKey, ivSpec); byte[] encryptedText = encryptionCipher.doFinal(clearText.getBytes("UTF-8")); String encryptedHex = ZiftrUtils.bytesToHexString(encryptedText); // Why are we appending these values? // AES requires a random initialization vector (IV). We save the IV // with the encrypted value so we can get it back later in decrypt() return new ZWEncryptedData(ivHex + encryptedHex); } catch (Exception e) { System.out.println("error message: " + e.getMessage()); throw new ZWKeyCrypterException("Unable to encrypt", e); } }
public static String decrypt(final String encrypted, SecretKey secretKey) { String plainText = null; try { final byte[] nonceAndCiphertext = DatatypeConverter.parseBase64Binary(encrypted); Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); final IvParameterSpec nonceIV = generateIVFromNonce(nonceAndCiphertext, 0, NONCE_SIZE, cipher.getBlockSize()); cipher.init(Cipher.DECRYPT_MODE, secretKey, nonceIV); final byte[] byteplaintext = cipher.doFinal(nonceAndCiphertext, NONCE_SIZE, nonceAndCiphertext.length - NONCE_SIZE); // note: this may return an invalid result if the value is tampered // with // it may even contain more or less characters plainText = new String(byteplaintext); } catch (final GeneralSecurityException e) { throw new IllegalStateException("Missing basic functionality from Java runtime", e); } return plainText; }
/** * Takes correctly padded data and encrypts it * * @param data correctly padded data * @return * @throws CryptoException */ public byte[] encrypt(byte[] data) throws CryptoException { try { byte[] ciphertext; if (useExplicitIv) { ciphertext = ArrayConverter.concatenate(encryptIv.getIV(), encryptCipher.doFinal(data)); } else { encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey, encryptIv); ciphertext = encryptCipher.doFinal(data); encryptIv = new IvParameterSpec( Arrays.copyOfRange( ciphertext, ciphertext.length - decryptCipher.getBlockSize(), ciphertext.length)); } return ciphertext; } catch (BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException ex) { throw new CryptoException(ex); } }
/** * * JS的RSA解密 * * * @param key 解密的密钥 * * @param raw 已经加密的数据 * * @return 解密后的明文 * * @throws Exception */ public static byte[] decryptByJs(String privateKey, byte[] raw) throws Exception { try { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); RSAPrivateKey privateK = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance( KEY_ALGORITHM, new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(cipher.DECRYPT_MODE, privateK); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (raw.length - j * blockSize > 0) { bout.write(cipher.doFinal(raw, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { throw new Exception(ExceptionUtil.getStackTraceAsString(e)); } }
public static String encrypt(final String secret, SecretKey secretKey) { String strCipherText = null; try { final byte[] plaintext = secret.getBytes(); final byte[] nonceAndCiphertext = new byte[NONCE_SIZE + plaintext.length]; Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); int offset = generateRandomNonce(nonceAndCiphertext, 0, NONCE_SIZE); final IvParameterSpec nonceIV = generateIVFromNonce(nonceAndCiphertext, 0, NONCE_SIZE, cipher.getBlockSize()); cipher.init(Cipher.ENCRYPT_MODE, secretKey, nonceIV); offset += cipher.doFinal(plaintext, 0, plaintext.length, nonceAndCiphertext, offset); if (offset != nonceAndCiphertext.length) { throw new IllegalStateException("Something wrong during encryption"); } strCipherText = DatatypeConverter.printBase64Binary(nonceAndCiphertext); } catch (final GeneralSecurityException e) { throw new IllegalStateException("Missing basic functionality from Java runtime", e); } return strCipherText; }
/** * * 加密 * * * @param key 加密的密钥 * * @param data 待加密的明文数据 * * @return 加密后的数据 * * @throws Exception */ public static byte[] encryptByJs(String publicKey, byte[] data) throws Exception { try { // 字符串转key byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); RSAPublicKey publicK = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance( KEY_ALGORITHM, new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int blockSize = cipher.getBlockSize(); // 获得加密块大小,如:加密前数据为128个byte,而key_size=1024 // 加密块大小为127 // byte,加密后为128个byte;因此共有2个加密块,第一个127 // byte第二个为1个byte int outputSize = cipher.getOutputSize(data.length); // 获得加密块加密后块大小 int leavedSize = data.length % blockSize; int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize; byte[] raw = new byte[outputSize * blocksSize]; int i = 0; while (data.length - i * blockSize > 0) { if (data.length - i * blockSize > blockSize) cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize); else cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize); // 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到 // ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了 // OutputSize所以只好用dofinal方法。 i++; } return raw; } catch (Exception e) { throw new Exception(ExceptionUtil.getStackTraceAsString(e)); } }
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()); }
protected IvParameterSpec getIv() { byte[] iv = new byte[writer.getBlockSize()]; System.arraycopy( "fldsjfodasjifudslfjdsaofshaufihadsf".getBytes(), 0, iv, 0, writer.getBlockSize()); return new IvParameterSpec(iv); }