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

Java 无法更改Base64解码器中的密码密钥,java,encryption,cryptography,base64,des,Java,Encryption,Cryptography,Base64,Des,我有一个预先编写的代码,用于对给定的纯文本进行加密,反之亦然 该类有3个方法,其中2个方法可分别用于加密和解密 public class SqlCipherUtil { private Cipher ecipher; private Cipher dcipher; public String encryptString(String pStrPlainText) { try { generateKey();

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

该类有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背后的概念是什么

要使用自定义组合键或自定义生成的键,应该做些什么

请回答这两个问题

该键的任何其他组合都会使字节数组的大小更大 小于8或小于7

我对此表示怀疑。您可能正在添加或删除错误的字符;或者在错误的位置。见:

是的,9字节不是DES的有效密钥长度。你可以把它缩短到合适的长度。因为base64字符串的长度为3x4个字符,将被解码为3x3=9个字符,所以您得到了9个字节。调整输出

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

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

要使用自定义组合键或自定义生成的键,应该做些什么

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

如果您的目标是对字符串进行编码和解码,请使用
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);


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

新的based-64编码密钥长度必须为12个字符,以一个字符结尾,并且只有一个字符

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

在编码键“rA/LUdBA/hA=”中,有12个字符,可以编码9个字节。但是最后一个字符是padding,这意味着最后一个字节应该被忽略,剩下8个字节

要使用自定义组合键或自定义生成的键,应该做些什么

首先,你不应该使用DES。它太脆弱和不安全了。但一般来说,在Java中生成安全密钥的正确过程是使用该类。对于(不安全的)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");
要使用密钥,请按如下方式解码:

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

那个初始化代码对我有用。。。你确定你已经得到了正确的代码吗?如果密钥仅为“rA/LUdBA/hA=”的话,代码对我来说很好用。如果我们改变钥匙,我会得到一个例外。自己试试,将密钥更改为其他密钥,在主程序中尝试调用新的SqlCipherUtil().encryptString(“jon skeet”);您将得到一个异常。如果密钥仅为“rA/LUdBA/hA=”,则代码对我来说可以正常工作。如果我改变钥匙,我会得到一个例外。您自己试试,将密钥更改为其他密钥,在主程序中尝试调用新的SqlCipherUtil().encryptString(“JoSO”);DES使用一个8字节的键,但忽略每个字节的lsb,或者原来lsb用于奇偶校验。