?? hybrid.java
字號:
if (dataStr != null) {
// close outputstream
try {
dataStr.close();
} catch (IOException e) {
;
}
}
}
}
/**
* Decrypts and verifies an inputstream (which must support mark/reset) with HMAC
*
* @param is inputstream to decrypt (NOTE: the inputstream must support mark/reset because it must be read three times)
* @param daos outputstream to store the decrypted data
* @param privKey the receiver's private key for decryption
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param mode encryption mode (e.g. "CBC")
* @param padding padding scheme (e.g."PKCS7Padding")
* @param bufferlength buffer length in bytes
* @throws IOException I/O errors
* @throws HeaderException thrown when package header is broken
* @throws InvalidHMACException thrown when the HMAC code is invalid
* @throws CryptoException all encryption errors
*/
public static void decryptAndVerifyHMAC(InputStream is
, DataOutputStream daos
, PrivateKey privKey
, String algorithm
, String mode
, String padding
, int bufferlength)
throws IOException, HeaderException, InvalidHMACException, CryptoException {
SecureRandom secRand;
Mac mac = null;
Cipher cipher = null;
Cipher decHMAC = null;
SecretKey symKey = null; // Symmetric key.
SecretKey macKey = null; // MAC key.
byte[] keyIV = null; // AES IV
byte[] macCode = null; // MAC code
DataInputStream dataIn = null;
MacInputStream macStr = null;
DataInputStream dataStr = null;
try {
Security.addProvider(new BouncyCastleProvider());
secRand = SecureRandom.getInstance("SHA1PRNG", "SUN");
dataIn = new DataInputStream(is);
int l = 0; // Universal length variable.
boolean ena = false; // Enable flag.. (Set when file/string header found)
boolean stop = false; // Stop flag.
// Setup RSA to decrypt secrets.
Cipher rsaEng = Cipher.getInstance("RSA/None/OAEPPadding", "BC");
rsaEng.init(Cipher.DECRYPT_MODE, privKey, secRand); // Initialize cipher for decryption.
while (!stop) {
try {
int cmd = dataIn.readShort(); // Read in block header.
if (cmd == FILE_HEADER) // File header.
{
ena = true; // Flag file header found.
continue;
}
if (cmd == DATA_BLOCK) // Read in data block
{
if (!ena) {
throw new HeaderException("Broken header");
}
l = dataIn.readInt(); // Read length.
dataIn.skip(l); // Skip this data.
continue;
}
if (cmd == FINAL_DATA_BLOCK) // Final data block.
{
if (!ena) {
throw new HeaderException("Broken header");
}
l = dataIn.readInt(); // Read length
dataIn.skip(l); // Skip this data.
continue;
}
if (cmd == HMAC_BLOCK) // MAC block.
{
if (!ena) {
throw new HeaderException("Broken header");
}
l = dataIn.readInt(); // Read length.
macCode = new byte[l]; // Create new array (l) in size.
dataIn.readFully(macCode); // Read in signature.
continue;
}
if (cmd == KEY_BLOCK) // Read in key block.
{
if (!ena) {
throw new HeaderException("Broken header");
}
l = dataIn.readInt(); // Read length.
byte[] d = new byte[l]; // Create new array (l) in size.
dataIn.readFully(d); // read in data.
// We must use a SecretKeySpec set up
// to convert the raw encoded key back into a SecretKey Object.
// The key is also decrypted before processing.
symKey = new SecretKeySpec(rsaEng.doFinal(d), algorithm);
continue;
}
if (cmd == IV_BLOCK) // Read in IV.
{
if (!ena) {
throw new HeaderException("Broken header");
}
l = dataIn.readInt(); // Read length
keyIV = new byte[l]; // Create new array for IV (l) in size.
dataIn.readFully(keyIV); // Read in IV.
keyIV = rsaEng.doFinal(keyIV); // Decrypt IV
continue;
}
if (cmd == HMAC_KEY_BLOCK) // Read lock.
{
if (!ena) {
throw new HeaderException("Broken header");
}
// Set up cipher to decrypt MAC
decHMAC = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
decHMAC.init(Cipher.DECRYPT_MODE, symKey, new IvParameterSpec(keyIV));
l = dataIn.readInt(); // Read Length
byte[] d = new byte[l]; // Create new byte array (l) in size.
dataIn.readFully(d); // Read
macKey = new SecretKeySpec(decHMAC.doFinal(d), "HMACSHA1"); // Decrypt lock.
continue;
}
} catch (EOFException eof) {
stop = true;
}
}
mac = Mac.getInstance("HMACSHA1", "BC"); // Mac algorithm based on SHA1 message digest.
mac.init(macKey); // initialize it with the mac key.
// Set up input stream wrappers.
is.reset();
macStr = new MacInputStream(is, mac);
dataStr = new DataInputStream(macStr);
int cmd = 0; // variable to store block header.
byte[] buf = new byte[bufferlength]; // Buffer to work in.
l = 0; // Universal length variable.
do {
cmd = dataStr.readShort(); // Read off block header/
if (cmd == DATA_BLOCK) // Skip HMAC block.
{
l = dataStr.readInt(); // Read length.
dataStr.read(buf, 0, l); // dummy read.
}
if (cmd == FINAL_DATA_BLOCK) // Skip the KEY Block
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == KEY_BLOCK) // Skip the KEY Block
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == IV_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == HMAC_KEY_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
} while (cmd != HMAC_BLOCK);
buf = mac.doFinal();
dataStr.close();
if (!MessageDigest.isEqual(buf, macCode)) {
throw new InvalidHMACException("Invalid HMAC");
}
cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
cipher.init(Cipher.DECRYPT_MODE, symKey, new IvParameterSpec(keyIV));
is.reset();
dataStr = new DataInputStream(is);
stop = false; // Loop breaker.
cmd = 0; // Variable to hold block header.
l = 0; // Universal length variable.
buf = new byte[bufferlength]; // A buffer to work in.
byte[] out = null; // Output buffer.
for (; ;) {
cmd = dataStr.readShort(); // Read in block header.
if (cmd == DATA_BLOCK) {
l = dataStr.readInt(); // Get length of data.
dataStr.readFully(buf, 0, l); // Read data.
out = cipher.update(buf, 0, l);
if (out != null) daos.write(out);
}
if (cmd == FINAL_DATA_BLOCK) {
l = dataStr.readInt(); // Length of data.
dataStr.readFully(buf, 0, l); // Read in data.
out = cipher.doFinal(buf, 0, l);
if (out != null) daos.write(out);
break;
}
// The following blocks and their content are skipped.
if (cmd == KEY_BLOCK) // Skip the KEY Block
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == IV_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == HMAC_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == HMAC_KEY_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.skip(l);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
throw new IOException(ioe.getMessage());
} catch (HeaderException he) {
he.printStackTrace();
throw new HeaderException(he.getMessage());
} catch (InvalidHMACException ihe) {
ihe.printStackTrace();
throw new InvalidHMACException(ihe.getMessage());
} catch (Exception ex) {
ex.printStackTrace();
throw new CryptoException(ex.getMessage());
}
}
/**
* Encrypt and sign a text
*
* @param text the text to encrypt and sign
* @param receiverKey the public key of the receiver
* @param signingKey the private key of the signer
* @param cert the signer's certificate
* @param signame the signature's algorithm (e.g."MD5withRSA")
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param seed for SecureRandom (optional)
* @param strength the keysize in bits (e.g. 128)
* @param mode encryption mode (e.g. "CBC")
* @param padding padding scheme (e.g."PKCS7Padding")
* @return ciphered and signed text
* @throws CryptoException encryption errors
*/
public static StringBuffer encryptAndSign(StringBuffer text
, PublicKey receiverKey
, PrivateKey signingKey
, X509Certificate cert
, String signame
, String algorithm
, byte[] seed
, int strength
, String mode
, String padding) throws CryptoException {
ByteArrayOutputStream bao = null;
DataOutputStream dao = null;
try {
bao = new ByteArrayOutputStream();
dao = new DataOutputStream(bao);
// encrypt text with HMAC
encryptAndSign(new ByteArrayInputStream(text.toString().getBytes()), dao, receiverKey, signingKey, cert, signame, algorithm, seed, strength, mode, padding, BUFFERSIZE_TEXT);
return new StringBuffer(new String(Base64.encode(bao.toByteArray())));
} catch (IOException ioe) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -