-1

我有一个预先编写的代码,用于加密给定的纯文本,反之亦然。

该类有 3 个方法,其中 2 个方法可分别用于加密和解密。

public class SqlCipherUtil {

    private Cipher ecipher;
    private Cipher dcipher;

    public String encryptString(String pStrPlainText) {

        try {
            generateKey();
            byte[] utf8 = pStrPlainText.getBytes("UTF8");
            byte[] enc = this.ecipher.doFinal(utf8);
            return new BASE64Encoder().encode(enc);

        } catch (Exception e) {
            e.printStackTrace();
        } 

        return null;
    }

    public String decryptString(String pStrCipherText){

        try {
            generateKey();
            byte[] dec = new BASE64Decoder().decodeBuffer(pStrCipherText);
            byte[] utf8 = this.dcipher.doFinal(dec);
            return new String(utf8, "UTF8");

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * This method is used to generate the encrypted key.
     */
    private void generateKey() {

        try {
            byte[] decodedStr = new BASE64Decoder().decodeBuffer("rA/LUdBA/hA=");
            SecretKey key = new SecretKeySpec(decodedStr, "DES");
            this.ecipher = Cipher.getInstance("DES");
            this.dcipher = Cipher.getInstance("DES");
            this.ecipher.init(1, key);
            this.dcipher.init(2, key);

        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
}

类中存在的键不能更改为 line 中的任何其他键byte[] decodedStr = new BASE64Decoder().decodeBuffer("rA/LUdBA/hA=");,并且它给出了异常。

java.security.InvalidKeyException: Invalid key length: 9 bytes
    at com.sun.crypto.provider.DESCipher.engineGetKeySize(DashoA13*..)
    at javax.crypto.Cipher.b(DashoA13*..)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)

我尝试了下面的代码,我在数组中得到了 8 个字节。

    public static void main(String[] args) throws IOException {
        byte[] decodedStr = new BASE64Decoder().decodeBuffer("rA/LUdBA/hA=");

        for(byte b : decodedStr){
            System.out.print(b);
            System.out.print(" ");
        }
    }

}

键的任何其他组合将使字节数组大小大于 8 或小于 7。

获取字节数组大小 8 背后的概念是什么?

使用自定义组合键或我们自定义生成的键应该怎么做?

请回答这两个问题。

4

3 回答 3

2

键的任何其他组合将使字节数组大小大于 8 或小于 7。

我不信。您可能添加或删除了错误的字符;或在错误的位置。见:http ://en.wikipedia.org/wiki/Base64

是的,9 个字节不是 DES 的有效密钥长度。您可以简单地将其缩短到适当的长度。你确实得到了 9 个字节,因为你的 base64 字符串是 3x4 字符长,它将被解码为 3x3 = 9 个字符。修剪输出。

获取字节数组大小 8 背后的概念是什么?

DES 使用 56 位密钥。8 字节 = 64 位,因此有足够的位用于密钥。

使用自定义组合键或我们自定义生成的键应该怎么做?

让用户输入至少有 7 个字符(56 位)的密钥。我真的不明白你为什么在这个示例中使用 base64 - 可能只是因为你从某个地方复制了它?你只需要几个随机字节。获得这些的常用方法是从用户提供的任何输入构建散列并使用该散列中的字节。

于 2012-09-25T08:03:36.413 回答
0

如果您的目标是对字符串进行编码和解码,请使用Base64.

    public class PasswordCodecHandler {
        Base64 codec = null;

        public PasswordCodecHandler() {
            codec = new Base64();
        }

        public String encode(String password) {
            byte[] temp;
            String encodedPassword = null;
            temp = codec.encode(password.getBytes());
            encodedPassword = new String(temp);
            return encodedPassword;
        }

        public String decode(byte[] encodedPassword) {
            byte[] temp;
            String decodedPassword;
            temp = codec.decode(encodedPassword);
            decodedPassword = new String(temp);
            return decodedPassword;
        }

        public static void main(String[] args) {
            PasswordCodecHandler passwordCodecHandler = new PasswordCodecHandler();
            String s1 = passwordCodecHandler.encode("password");
            System.out.println(s1);

            String s2 = passwordCodecHandler.encode("admin");
            System.out.println(s2);

            String s3 = passwordCodecHandler.encode("administrator");
            System.out.println(s3);

            String s4 = passwordCodecHandler.encode("123456");
            System.out.println(s4);

        }
    }

对于其他数据类型:可以java.lang.OutOfMemoryError根据您的内存分配大小

    /* Download apache common-io.xxx. jar*/

    public class CodecHandler {
        Base64 codec = null;

        public CodecHandler() {
            codec = new Base64();
        }

        public byte[] encode(byte[] decoded) {
            return codec.encode(decoded);
        }

        public byte[] decode(byte[] encoded) {
            return codec.decode(encoded);
        }

        public static void main(String[] args) throws IOException {
            File file = new File("D:/Test.mp4");
            byte[] fileByteArray = FileUtils.readFileToByteArray(file);
            CodecHandler codecHandler = new CodecHandler();
            byte[] encoded = codecHandler.encode(fileByteArray);
            System.out.println("Byte Size : " + encoded.length);
            byte[] decode = codecHandler.decode(encoded);
            FileUtils.writeByteArrayToFile(new File("C:/Test.mp4"), decode);


        }
    }
于 2012-09-25T08:23:50.950 回答
0

获取字节数组大小 8 背后的概念是什么?

您的新的基于 64 编码的密钥长度必须为 12 个字符,以一个且只有一个=字符结尾。

在 base-64 中,字符=是填充字符,它只能出现在编码字符串的末尾。Base-64 编码从每个 3 字节的输入块中输出一个 4 个字符的块。如果输入长度不是 3 的倍数,则填充最后一个块。

编码后的密钥“rA/LUdBA/hA=”中有12个字符,可以编码9个字节。但是最后一个字符是填充,这意味着最后一个字节应该被忽略,留下8个字节。

应该怎么做才能使用自定义组合键或我们自定义生成的键?

首先,您不应该使用 DES。它太虚弱和不安全。但总的来说,在 Java 中生成安全密钥的正确过程是使用KeyGenerator类。对于(不安全的)DES,您可以生成一个密钥并使用 base-64 对其进行编码,如下所示:

import java.util.Base64;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

…

KeyGenerator gen = KeyGenerator.getInstance("DES");
gen.init(56);
SecretKey secret = gen.generateKey();
String b64 = Base64.getEncoder().encodeToString(secret.getEncoded());
System.out.println(b64);

要使用密钥,请按如下方式对其进行解码:

import java.util.Base64;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeySpec;

…

SecretKey key = new SecretKeySpec(Base64.getDecoder().decode(b64), "DES");
于 2017-03-09T18:09:12.500 回答