?? hybrid.java
字號:
/*
Name: Hybrid.java
Licensing: LGPL
API: Sun (http://java.sun.com) JCE 1.2.2 API (cleanroom implementation by Bouncy Castle)
Provider: Bouncy Castle (http://www.bouncycastle.org)
Disclaimer:
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE
IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE
PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR)
ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY
CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED
HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
(C) Copyright 2003 Gert Van Ham
*/
package net.sourceforge.jcetaglib.lib;
import net.sourceforge.jcetaglib.exceptions.CryptoException;
import net.sourceforge.jcetaglib.exceptions.HeaderException;
import net.sourceforge.jcetaglib.exceptions.InvalidHMACException;
import net.sourceforge.jcetaglib.exceptions.InvalidSignatureException;
import net.sourceforge.jcetaglib.tools.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* Hybrid encryption & decryption routines for use with BouncyCastle JCE provider
*
* @author Gert Van Ham
* @author hamgert@users.sourceforge.net
* @author http://jcetaglib.sourceforge.net
* @version $Id: Hybrid.java,v 1.3 2004/04/15 07:28:25 hamgert Exp $
*/
public class Hybrid {
// buffersizes in bytes
private static int BUFFERSIZE_TEXT = 1204;
private static int BUFFERSIZE_FILE = 8192;
static final int FILE_HEADER = 0x7e01; // File header.
static final int DATA_BLOCK = 1; // Data block
static final int FINAL_DATA_BLOCK = 2; // Final data block.
static final int HMAC_BLOCK = 3; // HMAC block
static final int SIG_BLOCK = 3; // Signature block
static final int CERT_BLOCK = 4; // Certificate block.
static final int KEY_BLOCK = 16; // Keystore block
static final int IV_BLOCK = 17; // IV block
static final int LOCK_BLOCK = 18; // Locking block
static final int HMAC_KEY_BLOCK = 18;
/**
* Encrypts text with an HMAC
*
* @param text text to encrypt
* @param receiverKey the receiver's public key for encrypting the symmetric key
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param seed 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 encrypted string in BASE64 format
* @throws CryptoException encryption errors
**/
public static StringBuffer encryptWithHMAC(StringBuffer text
, PublicKey receiverKey
, 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
encryptWithHMAC(new ByteArrayInputStream(text.toString().getBytes()), dao, receiverKey, algorithm, seed, strength, mode, padding, BUFFERSIZE_TEXT);
return new StringBuffer(new String(Base64.encode(bao.toByteArray())));
} catch (IOException ioe) {
ioe.printStackTrace();
throw new CryptoException(ioe.getMessage());
} finally {
if (dao != null) {
// close outputstream
try {
dao.close();
} catch (IOException e) {
;
}
}
}
}
/**
* Encrypts file with an HMAC
*
* @param file file to encrypt
* @param newfile encrypted file
* @param receiverKey the receiver's public key for encrypting the symmetric key
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param seed 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")
* @throws CryptoException encryption errors
* @throws IOException I/O errors
**/
public static void encryptFileWithHMAC(String file
, String newfile
, PublicKey receiverKey
, String algorithm
, byte[] seed
, int strength
, String mode
, String padding) throws CryptoException, IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
DataOutputStream dao = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream(newfile);
dao = new DataOutputStream(fos);
// encrypt file
encryptWithHMAC(fis, dao, receiverKey, algorithm, seed, strength, mode, padding, BUFFERSIZE_FILE);
} catch (IOException ioe) {
ioe.printStackTrace();
throw new IOException(ioe.getMessage());
} finally {
if (dao != null) {
// close outputstream
try {
dao.close();
} catch (IOException e) {
;
}
}
if (fis != null) {
// close outputstream
try {
fis.close();
} catch (IOException e) {
;
}
}
}
}
/**
* Encrypts any inputstream with an HMAC
*
* @param is inputstream to encrypt
* @param daos outputstream to store the encrypted data
* @param receiverKey the receiver's public key for encrypting the symmetric key
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param seed 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")
* @param bufferlength buffer length in bytes
* @throws CryptoException encryption errors
* @throws IOException I/O errors
**/
public static void encryptWithHMAC(InputStream is
, DataOutputStream daos
, PublicKey receiverKey
, String algorithm
, byte[] seed
, int strength
, String mode
, String padding
, int bufferlength)
throws CryptoException, IOException {
MacOutputStream macStr = null;
DataOutputStream dataStr = null;
try {
Security.addProvider(new BouncyCastleProvider());
SecureRandom secRand = Seed.getSecureRandom(seed);
// Generate symmetric key
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm, "BC");
keyGen.init(strength, secRand);
Key symKey = keyGen.generateKey();
// Instantiate Symmetric cipher for encryption.
Cipher outputCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
outputCipher.init(Cipher.ENCRYPT_MODE, symKey, secRand);
// Get key and IV for cipher so that they can be later
// encrypted to build a header.
byte[] keyEnc = symKey.getEncoded();
byte[] keyIV = outputCipher.getIV();
// Setup HMAC
Mac mac = Mac.getInstance("HMACSHA1", "BC");
byte[] macKeyBytes = new byte[20]; // Set to correct length for HMACSHA1
secRand.nextBytes(macKeyBytes); // Fill with random data,
Key macKey = new SecretKeySpec(macKeyBytes, "HMACSHA1");
mac.init(macKey); // Initialize.
// Setup RSA to encrypt secrets.
Cipher rsaEng = Cipher.getInstance("RSA/None/OAEPPadding", "BC");
rsaEng.init(Cipher.ENCRYPT_MODE, receiverKey, secRand);
// Setup to process MAC
macStr = new MacOutputStream(daos, mac);
dataStr = new DataOutputStream(macStr);
// Form HEADER for the encrypted string
dataStr.writeShort(FILE_HEADER); // Write a file or string header.
// Write out a block for the key of the cipher.
dataStr.writeShort(KEY_BLOCK); // Block header.
byte[] tmp = rsaEng.doFinal(keyEnc); // Encrypt it with RSA.
dataStr.writeInt(tmp.length); // Write length.
dataStr.write(tmp); // Write data.
Clean.blank(tmp); // Erase tmp array.
// Write out IV block
dataStr.writeShort(IV_BLOCK); // Block header
tmp = rsaEng.doFinal(keyIV); // Encrypt with RSA.
dataStr.writeInt(tmp.length); // Write length.
dataStr.write(tmp); // Write data.
Clean.blank(tmp); // Erase tmp array.
// Write out key for HMAC.
dataStr.writeShort(HMAC_KEY_BLOCK); // Write header.
tmp = outputCipher.doFinal(macKey.getEncoded()); // Encrypt
dataStr.writeInt(tmp.length); // Write length.
dataStr.write(tmp); // Write data.
Clean.blank(tmp); // Erase tmp array.
// Reset cipher back to original
//outputCipher.init(Cipher.ENCRYPT_MODE,symKey,new IvParameterSpec(keyIV)); // initialize with aes_key.
// Encrypt the message
int l = 0; // Universal length variable.
byte[] buf = new byte[bufferlength]; // A buffer to work in.
byte[] out = null; // Output buffer.
// Read while length is > -1
while ((l = is.read(buf)) > -1) {
out = outputCipher.update(buf, 0, l); // Encrypt data.
if (out != null) {
dataStr.writeShort(DATA_BLOCK); // Write data block header.
dataStr.writeInt(out.length); // Write length.
dataStr.write(out); // Write encrypted data.
}
}
// This is the last block
out = outputCipher.doFinal(); // Do final encryption.
dataStr.writeShort(FINAL_DATA_BLOCK); // Write header.
dataStr.writeInt(out.length); // Write length.
dataStr.write(out); // Write Data.
Clean.blank(buf); // Clear buffer.
buf = null; // Set Null
// Write out MAC block
dataStr.writeShort(HMAC_BLOCK); // Write Header.
dataStr.flush(); // Flush it..
tmp = mac.doFinal(); // Get MAC code.
dataStr.writeInt(tmp.length); // Write length.
dataStr.write(tmp); // Write data.
Clean.blank(tmp); // Clear.
} catch (IOException ioe) {
ioe.printStackTrace();
throw new IOException(ioe.getMessage());
} catch (Exception ex) {
ex.printStackTrace();
throw new CryptoException(ex.getMessage());
} finally {
if (dataStr != null) {
try {
dataStr.close();
} catch (IOException ioe) {
;
}
}
}
}
/**
* Decrypts and verifies text with HMAC
*
* @param text the text to decrypt
* @param privKey the receiver's private key for decryption
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param mode encryption mode (e.g. "CBC")
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -