?? hybrid.java
字號:
, String signame
, String algorithm
, String mode
, String padding
, int bufferlength)
throws CryptoException, HeaderException, InvalidSignatureException, IOException {
byte[] lockData = null; // Lock data
X509Certificate cert = null; // Senders Authentication Certificate.
SecretKey symKey = null; // Symmetric key.
byte[] keyIV = null; // AES IV
byte[] sigCode = null; // Signature.
DataInputStream dataIn = null;
try {
Security.addProvider(new BouncyCastleProvider());
SecureRandom 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 == Hybrid.FILE_HEADER) // File header.
{
ena = true; // Flag file header found.
continue;
}
if (cmd == Hybrid.DATA_BLOCK) // Read in data block
{
if (!ena) {
throw new Exception("Broken header");
}
l = dataIn.readInt(); // Read length.
dataIn.skip(l); // Skip this data.
continue;
}
if (cmd == Hybrid.FINAL_DATA_BLOCK) // Final data block.
{
if (!ena) {
throw new Exception("Broken header");
}
l = dataIn.readInt(); // Read length
dataIn.skip(l); // Skip this data.
continue;
}
if (cmd == Hybrid.SIG_BLOCK) // Signature block.
{
if (!ena) {
throw new Exception("Broken header");
}
l = dataIn.readInt(); // Read length.
sigCode = new byte[l]; // Create new array (l) in size.
dataIn.readFully(sigCode); // Read in signature.
continue;
}
if (cmd == Hybrid.KEY_BLOCK) // Read in key block.
{
if (!ena) {
throw new Exception("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 == Hybrid.IV_BLOCK) // Read in IV.
{
if (!ena) {
throw new Exception("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 == Hybrid.LOCK_BLOCK) // Read lock.
{
if (!ena) {
throw new Exception("Broken header");
}
// Set up cipher to decrypt lock data.
Cipher decLock = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
decLock.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 lock.
lockData = decLock.doFinal(d); // Decrypt lock.
decLock = null; // Make null;
continue;
}
if (cmd == Hybrid.CERT_BLOCK) // Senders certificate block.
{
if (!ena) {
throw new Exception("Broken header");
}
l = dataIn.readInt(); // Read Length
byte[] d = new byte[l]; // Create new array (l) in length.
dataIn.readFully(d); // Read in certificate.
CertificateFactory cf = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(d));
continue;
}
} catch (EOFException eof) {
stop = true;
}
}
// return the certificate signer
signercert.setCert(cert);
Signature sig = Signature.getInstance(signame, "BC"); // Set up signature object.
sig.initVerify(cert); // Initialize with senders certificate.
sig.update(lockData); // Update with lock data.
// Set up input stream wrappers.
is.reset();
SignatureInputStream sigStr = new SignatureInputStream(is, sig);
DataInputStream dataStr = new DataInputStream(sigStr);
int cmd = 0; // variable to store block header.
byte[] buf = new byte[bufferlength]; // Buffer to work in.
l = 0; // Universal length variable.
for (; ;) {
cmd = dataStr.readShort(); // Read off block header/
if (cmd == Hybrid.DATA_BLOCK) // Skip HMAC block.
{
l = dataStr.readInt(); // Read length.
dataStr.read(buf, 0, l); // dummy read.
}
if (cmd == Hybrid.FINAL_DATA_BLOCK) // Skip the KEY Block
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == Hybrid.KEY_BLOCK) // Skip the KEY Block
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == Hybrid.IV_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == Hybrid.LOCK_BLOCK) // Skip the lock block.
{
l = dataStr.readInt();
dataStr.read(buf, 0, l); // dummy read
}
if (cmd == Hybrid.CERT_BLOCK) // Skip the cert block.
{
l = dataStr.readInt();
dataStr.read(buf, 0, l);// dummy read
}
if (cmd == Hybrid.SIG_BLOCK) {
break;
}
}
dataStr.close();
// throw an exception when the signature could not be verified or is invalid
if (!sig.verify(sigCode)) {
throw new InvalidSignatureException("Signature is invalid");
}
Cipher cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
cipher.init(Cipher.DECRYPT_MODE, symKey, new IvParameterSpec(keyIV));
//FileOutputStream outStr = new FileOutputStream(newfilename); // Where to save
// Input source file, via DataInputStream wrapper.
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 == Hybrid.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 == Hybrid.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 == Hybrid.KEY_BLOCK) // Skip the KEY Block
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == Hybrid.IV_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == Hybrid.LOCK_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == Hybrid.CERT_BLOCK) // Skip the IV block.
{
l = dataStr.readInt();
dataStr.skip(l);
}
if (cmd == Hybrid.SIG_BLOCK) {
l = dataStr.readInt();
dataStr.skip(l);
}
}
Clean.blank(buf); // Erase buffer.
buf = null; // Set null.
dataStr.close();
} catch (IOException ioe) {
ioe.printStackTrace();
throw new IOException(ioe.getMessage());
} catch (HeaderException he) {
he.printStackTrace();
throw new HeaderException(he.getMessage());
} catch (InvalidSignatureException ise) {
ise.printStackTrace();
throw new InvalidSignatureException(ise.getMessage());
} catch (Exception ex) {
ex.printStackTrace();
throw new CryptoException(ex.getMessage());
}
}
/**
*
*
* @param file the file to decrypt and verify
* @param newfile the decrypted file
* @param privKey the private key of the receiver
* @param signercert returns the signer's certificate
* @param signame the signature's algorithm (e.g."MD5withRSA")
* @param algorithm encryption algorithm (e.g. "Rijndael")
* @param mode encryption mode (e.g. "CBC")
* @param padding padding scheme (e.g."PKCS7Padding")
* @throws IOException I/O errors
* @throws HeaderException thrown when package header is broken
* @throws InvalidSignatureException thrown when the signature is invalid
* @throws CryptoException all encryption errors
*/
public static void decryptFileAndVerify(String file
, String newfile
, PrivateKey privKey
, SignerCertificate signercert
, String signame
, String algorithm
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -