无法更改Base64解码器中的密钥

时间:2012-09-25 07:34:10

标签: java encryption cryptography base64 des

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

该类有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();
        } 
    }
}

班级中存在的密钥不能更改为任何其他密钥 在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的概念是什么?

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

请回答这两个问题。

3 个答案:

答案 0 :(得分:2)

  

该键的任何其他组合将使字节数组大小更多   超过8或少于7。

我对此表示怀疑。您可能正在添加或删除错误的字符;或者在错误的位置。请参阅:http://en.wikipedia.org/wiki/Base64

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

  

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

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

  

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

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

答案 1 :(得分: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);


        }
    }

答案 2 :(得分: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");