2012-09-25 101 views
-1

我有一个预先编写的代码,用于对给定的纯文本进行加密,反之亦然。无法更改Base64解码器中的密码密钥

该类有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的概念少了?

应该如何使用自定义组合键或我们的自定义生成的键?

请回答这两个问题。

+0

在初始化代码对我的作品......你确定吗?你已经准备好了那些代码? –

+0

如果密钥只是“rA/LUdBA/hA =”,代码对我来说工作正常。 如果我们改变密钥,我会得到一个异常。 尝试一下自己,将密钥更改为不同的密钥, 在主程序中尝试调用 新的SqlCipherUtil()。encryptString(“jon-skeet”); 你会得到一个例外。 – bali208

回答

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

     } 
    } 

对于其他数据类型:它可以根据你的内存分配大小

/* 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

密钥的任何其它组合将使字节数组的大小更 大于8或小于7

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

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

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

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

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

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

+0

如果密钥只是“rA/LUdBA/hA =”,代码对我来说工作正常。如果我改变密钥,我会得到一个异常。自己尝试一下,将密钥更改为不同的密钥,在主程序中尝试调用新的SqlCipherUtil()。encryptString(“JoSO”); – bali208

+0

DES使用8字节密钥,但忽略每个字节的LSB,原来LSB用于奇偶校验。 – zaph

0

什么是背后得到字节数组的大小8概念是java.lang.OutOfMemoryError

你的新的基于-64 –编码的密钥必须是12个字符长,一个,只有一个,=字符结尾。

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

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

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

首先,你不应该使用DES。这太弱,不安全。但总的来说,在Java中生成安全密钥的正确过程是使用KeyGenerator类。对于(不安全)DES,即可生成密钥,并与基地-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");