简体   繁体   English

使用salt和迭代进行3des java加密/解密

[英]3des java encryption/decryption with salt and iterations

In the decrypt class, I cant get it to correctly decrypt. 在解密类中,我无法正确解密。 I've verified in the decrypt class that my salt and my ciphertext still carries the same values before I convert them back to bytes. 我已经在解密类中验证了我的盐和我的密文在将它们转换回字节之前仍然具有相同的值。

The program itself doesn't given an error however when I compile, I'll encrypt, save it to the string encryptPhrase and then decrypt it in the decrypt method and I cant seem to get it to decrypt properly. 程序本身没有给出错误但是当我编译时,我将加密,将其保存到字符串encryptPhrase然后在解密方法中解密它我似乎无法正确解密它。 I've marked in comments where the issue is and gives a badpadding exception, however there is no padding? 我在注释中标记了问题所在并给出了badpadding异常,但是没有填充?

The odd thing is... if i take out everything in the decrypt method and return just encryptPhrase, it actually returns the correct plain text. 奇怪的是......如果我取出decrypt方法中的所有内容并返回only encryptPhrase,它实际上会返回正确的纯文本。

Any help would be appreciated. 任何帮助,将不胜感激。 Thanks! 谢谢! :) :)

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;

public class PasswordEncryption {

private static int ITERATIONS = 1000;
private static String saltString;
private static String ciphertextString;
private static String encryptPhrase;

private static void usage(){
    System.err.println("Usage: java PBE -e|-d password text");
    System.exit(1);
}

public static void main(String[] args) throws Exception{

    scan = new Scanner(System.in);

    System.out.println("Please enter plain text: ");
    String text = scan.nextLine();
    System.out.println("Please enter password to encrypt plain text: ");

    char [] pw = scan.nextLine().toCharArray();
    int option=3;

    while (option!=0){
    System.out.println("Are we encrypting(1) or decrypting(2) or Exit(0)? " );
    option = scan.nextInt();
    String output="exiting program";

    if (option == 1)
        output = encrypt(pw, text);
    else if (option ==2)
        output = decrypt(pw,text);
    System.out.println("Output: " +output);
    }

}
private static Scanner scan;

private static String encrypt(char[] password, String plaintext) throws Exception {

    //create random salt
    byte[]  salt = new byte[8];
    SecureRandom random = new SecureRandom();
    random.nextBytes(salt);

    //create key based on password
    int iterationCount = ITERATIONS;
    PBEKeySpec pbeSpec = new PBEKeySpec(password, salt, iterationCount);
    SecretKeyFactory keyFact = SecretKeyFactory.getInstance("PBEWithSHAAnd3KeyTripleDES");

    //create a cipher
    Cipher myCipher = Cipher.getInstance("PBEWithSHAAnd3KeyTripleDES");

    Key encryptKey = keyFact.generateSecret(pbeSpec);
    myCipher.init(Cipher.ENCRYPT_MODE, encryptKey);

    byte[] cipherText = myCipher.doFinal();
    System.out.println("Encrypted Text: " +toString(cipherText));

    //produce salt to string
    saltString = salt.toString();
    System.out.println("SALT: " +saltString);

    //produce cipher text to string
    ciphertextString = toString(cipherText);

    //stores salt and cipher string in encryptPhrase
    encryptPhrase = saltString+ciphertextString;

    return saltString+ciphertextString;
}

public static String decrypt(char[] password, String encryptPhrase) throws Exception{
    //split the encryption data into salt and ciphertext
    //System.out.println("encrypt Phrase: " +encryptPhrase);


    //convert salt into bytearray
    byte[] bsalt = toByteArray(saltString);
    //convert ciphertext into bytearray
    byte[] bciphert= toByteArray(ciphertextString);

    //produce cipher

    /////////////////////////////////////////////////////////////////////       
    int iterationCount = ITERATIONS;
    PBEKeySpec pbeSpec = new PBEKeySpec(password, bsalt, iterationCount);
    //use SHA and 3DES

    //create the key
    SecretKeyFactory keyFact = SecretKeyFactory.getInstance("PBEWithSHAAnd3KeyTripleDES");
    Cipher cDec = Cipher.getInstance("PBEWithSHAAnd3KeyTripleDES");
    Key sKey = keyFact.generateSecret(pbeSpec);

    //perform decryption
    cDec.init(cDec.DECRYPT_MODE,sKey);

    byte [] plainTextb = cDec.doFinal(bciphert); //gives me an error here. Says BadPaddingException: pad block corrupted?

    String plainText = toString(plainTextb); 

    return plainText;
    //return encryptPhrase;

}

/**
 * Convert a byte array of 8 bit characters into a String.
 * 
 *@param bytes the array containing the characters
 * @param length the number of bytes to process
 * @return a String representation of bytes
 */
public static String toString(byte[] bytes, int length)
{
    char[]  chars = new char[length];

    for (int i = 0; i != chars.length; i++)
    {
        chars[i] = (char)(bytes[i] & 0xff);
    }

    return new String(chars);
}

/**
 * Convert a byte array of 8 bit characters into a String.
 * 
 * @param bytes the array containing the characters
 * @return a String representation of bytes
 */
public static String toString( byte[]   bytes)
{
    return toString(bytes, bytes.length);
}

/**
 * Convert the passed in String to a byte array by
 * taking the bottom 8 bits of each character it contains.
 * 
 * @param string the string to be converted
 * @return a byte array representation
 */
public static byte[] toByteArray(String string)
{
    byte[]  bytes = new byte[string.length()];
    char[]  chars = string.toCharArray();

    for (int i = 0; i != chars.length; i++)
    {
        bytes[i] = (byte)chars[i];
    }

    return bytes;
}
private static String digits = "0123456789abcdef";

public static String toHex(byte[] data, int length)
{
    StringBuffer buf = new StringBuffer();

    for (int i=0; i!= length; i++)
    {
        int v = data[i] & 0xff;

        buf.append(digits.charAt(v >>4));
        buf.append(digits.charAt(v & 0xf));
    }
    return buf.toString();

}

/**
 * Return the passed in byte array as a hex string.
 * 
 * @param data the bytes to be converted.
 * @return a hex representation of data.
 */

public static String toHex(byte[] data)
{
    return toHex(data, data.length);
}
}

Yet another confusion between bytes and characters. 字节和字符之间的另一个混淆。 Could have guessed. 可能已经猜到了。 Please look up the base 64 encoding and see why it exists. 请查看base 64编码并查看其存在的原因。 Then note the implementation of Object.toString() and lookup character encoding (don't use new String(byte[]) on randomized bytes). 然后注意Object.toString()和查找字符编码的实现(不要在随机化字节上使用new String(byte[]) )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM