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

标签 java encryption 3des

在解密类中,我无法让它正确解密。我已经在解密类中验证了我的盐和密文在将它们转换回字节之前仍然带有相同的值。

程序本身没有给出错误,但是当我编译时,我将加密,将其保存到字符串 encryptPhrase 中,然后在解密方法中对其进行解密,但我似乎无法正确解密。我已在评论中标记了问题所在,并给出了 badpadding 异常,但是没有填充?

奇怪的是......如果我取出解密方法中的所有内容并仅返回 encryptPhrase,它实际上会返回正确的纯文本。

如有任何帮助,我们将不胜感激。谢谢! :)

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);
}
}

最佳答案

字节和字符之间的另一个混淆。本来可以猜到的。请查找 Base 64 编码并了解它存在的原因。然后注意 Object.toString() 的实现和查找字符编码(不要在随机字节上使用 new String(byte[]))。

关于java - 3des java 使用盐和迭代进行加密/解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11420945/

相关文章:

java - 将 3DES 存储在字符串中而不是 CipherOutputStream

java - 什么是强拉及其特点?

java - 在客户端-服务器应用程序中使用 RSA 时为 "UnsupportedEncodingException: SHA"

php - 如何为多个用户存储加密文件

javascript - Node.JS 中的 3des 加密返回无效的 IV 长度

Golang 3DES 部分解密加密字符串

java - 我怎样才能让javac搜索类路径的子目录?

java - 无法修复错误 : Cannot resolve symbol 'OnClickListener'

java.lang.RuntimeException : How do I solve this crash? 是什么原因造成的?

java - 如何让 WMQ Explorer 与 WMQ AMS 配合使用