2017-01-14 9 views
0

約1時間は試してみました。私はちょうどJavaの暗号化を試してみたかっただけで、私は理解していない多くのエラーメッセージで困惑しました。 in the javadocsのキーをAESのキーにする必要がある時間は56秒ですが、56ビットという長さのバイト配列を持っていなければならないと思っていました。しかし、それは動作していないようです。ここでは、スタックトレースは次のとおりです。Java Cipherに無効なキーの長さがあると言われました

java.security.InvalidKeyException: Invalid key length: 7 bytes null 
    at com.sun.crypto.provider.DESCipher.engineGetKeySize(DESCipher.java:373) 
    at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1067) 
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1038) 
    at javax.crypto.Cipher.implInit(Cipher.java:805) 
    at javax.crypto.Cipher.chooseProvider(Cipher.java:864) 
    at javax.crypto.Cipher.init(Cipher.java:1396) 
    at javax.crypto.Cipher.init(Cipher.java:1327) 
    at com.skrelpoid.secure.Crypt.encrypt(Crypt.java:34) 
    at com.skrelpoid.secure.Crypt.main(Crypt.java:95) 
Exception in thread "main" java.lang.NullPointerException 
    at com.skrelpoid.secure.Crypt.decrypt(Crypt.java:47) 
    at com.skrelpoid.secure.Crypt.main(Crypt.java:97)` 

そしてここでは、私のコードは次のとおりです。誰かが私にはそのコードが動作するように得るのを助けることができれば

import java.security.NoSuchAlgorithmException; 
import java.util.Random; 

import javax.crypto.Cipher; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

// adapted from http://stackoverflow.com/a/1205272/ 
public class Crypt { 
    private static byte[] ivBytes; 
    private static Cipher cipher; 
    private static SecretKeySpec keySpec; 
    private static IvParameterSpec ivSpec; 
    private static Random random; 
    private static long seed; 

    private Crypt() { 
    } 

    private static byte[] ivBytes() { 
     random.setSeed(seed); 
     byte[] bytes = new byte[7]; 
     random.nextBytes(bytes); 
     return bytes; 
    } 

    public static String encrypt(String key, String input) { 
     prepare(key); 
     byte[] inputBytes = input.getBytes(); 
     try { 
      cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 
      byte[] encrypted = new byte[cipher.getOutputSize(inputBytes.length)]; 
      int enc_len = cipher.update(inputBytes, 0, inputBytes.length, encrypted, 0); 
      enc_len += cipher.doFinal(encrypted, enc_len); 
      return new String(encrypted); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      return null; 
     } 
    } 

    public static String decrypt(String key, String input) { 
     prepare(key); 
     byte[] inputBytes = input.getBytes(); 
     try { 
      cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); 
      byte[] decrypted = new byte[cipher.getOutputSize(inputBytes.length)]; 
      int dec_len = cipher.update(inputBytes, 0, inputBytes.length, decrypted, 0); 
      dec_len += cipher.doFinal(decrypted, dec_len); 
      return new String(decrypted); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      return null; 
     } 
    } 

    private static void prepare(String key) { 
     byte[] keyBytes = new byte[7]; 
     byte[] bytesFromKey = key.getBytes(); 
     int length = keyBytes.length < bytesFromKey.length ? keyBytes.length : bytesFromKey.length; 
     System.arraycopy(bytesFromKey, 0, keyBytes, 0, length); 
     // if the length is smaller then keyBytes length, there are trailing 
     // zeros in the keyBytes. Fill them with the use of the seed; 
     if (length < keyBytes.length) { 
      random.setSeed(seed); 
      byte[] newBytes = new byte[keyBytes.length - length]; 
      random.nextBytes(newBytes); 
      System.arraycopy(newBytes, 0, keyBytes, length, newBytes.length); 
     } 

     keySpec = new SecretKeySpec(keyBytes, "DES"); 
     ivSpec = new IvParameterSpec(ivBytes); 
     try { 
      cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void init(String id) { 
     seed = id.hashCode(); 
     random = new Random(seed); 
     ivBytes = ivBytes(); 
    } 

    public static final void main(String[] args) { 
     init("123456"); 
     String str = "ILikeTurtles"; 
     String key = "KEY123"; 
     String encrypted = encrypt(key, str); 
     System.out.println(encrypted); 
     System.out.println(decrypt(key, encrypted)); 
    } 
} 

私は本当にいただければ幸いです。 ありがとうございます。

+0

AESとDESは、異なる鍵サイズの異なる暗号化アルゴリズムです。 DESは8バイトで56ビットのキーを持ち、AESは16,24,32バイトの128,192,256ビットの3つのキーサイズをサポートしています。 DESはもはや安全であるとみなされておらず、新しい作業に使用すべきではありません。 DESはAESに取って代わられました.AESを使用してください。 – zaph

答えて

3

DESには8バイトのキーと8バイトのIVが必要です。

+0

私は本当にそれを知っていたはずです。結局のところ、javadocは長さが56である必要があると言います。とにかく感謝します。 – Skrelp

+1

意味のあるビットと8個のパリティビット、合計64ビット= 8バイトです。末尾の4バイトはバグがあることを意味します。 –

+0

歴史的に、各バイトのlsbはパリティであり、最近ほとんど例外なく無視されています。 – zaph

関連する問題