0

私は本当にこれを自分で理解することができないので、助けてください。これは、128 ビット AES を使用して既存のファイル keeper.txt の内容を暗号化し、暗号化されたテキストを Encrypted.txt と呼ばれる新しく作成されたファイルに入れ、Encrypted.txt の内容を Decrypted.txt と呼ばれる新しく作成されたファイルに復号化するプログラムです。

このプログラムが実行されるたびに、暗号化用のランダム キーが生成されます。

誰かに Encrypted.txt ファイルを渡す必要があるかどうか、また、このコードを使用して、またはこのコードをわずかに変更して、後でファイルを復号化する方法を見つけようとしています。

このプログラムによって生成されたキーを彼に送信することはできないと思います..そうですか? system.out を使用してキーを印刷しようとすると、キーが表示されません。

私を助けてください

package org.temp2.cod1;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;

import java.security.spec.AlgorithmParameterSpec;

public class AESEncrypter
{
Cipher ecipher;
Cipher dcipher;

public AESEncrypter(SecretKey key)
{
// Create an 8-byte initialization vector
byte[] iv = new byte[]
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};

AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
try
{
ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

// CBC requires an initialization vector
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
}
catch (Exception e)
{
e.printStackTrace();
}
}

// Buffer used to transport the bytes from one stream to another
byte[] buf = new byte[1024];

public void encrypt(InputStream in, OutputStream out)
{
try
{
// Bytes written to out will be encrypted
out = new CipherOutputStream(out, ecipher);

// Read in the cleartext bytes and write to out to encrypt
int numRead = 0;
while ((numRead = in.read(buf)) >= 0)
{
out.write(buf, 0, numRead);
}
out.close();
}
catch (java.io.IOException e)
{
}
}

public void decrypt(InputStream in, OutputStream out)
{
try
{
// Bytes read from in will be decrypted
in = new CipherInputStream(in, dcipher);

// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0)
{
out.write(buf, 0, numRead);
}
out.close();
}
catch (java.io.IOException e)
{
}
}

public static void main(String args[])
{
try
{
// Generate a temporary key. In practice, you would save this key.
// See also e464 Encrypting with DES Using a Pass Phrase.

KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey key = kgen.generateKey();

// Create encrypter/decrypter class
AESEncrypter encrypter = new AESEncrypter(key);

// Encrypt
encrypter.encrypt(new FileInputStream("C:\\keeper.txt"),new FileOutputStream("C:\\Encrypted.txt"));
// Decrypt
encrypter.decrypt(new FileInputStream("C:\\Encrypted.txt"),new FileOutputStream("C:\\Decrypted.txt"));
}
catch (Exception e)
{
e.printStackTrace();
}
}
} 
4

2 に答える 2

0

を呼び出すことで、キーのエンコードされたバージョンを取得できます。

   byte[] keyBytes = secretKey.getEncoded();

AES の場合、エンコーディングは実際には関係ないため、生のバイト (128 ビットの場合は 16 バイト) を取得します。keyBytes はバイナリであるため、印刷できません。テキスト形式で送信する必要がある場合は、16 進数または base64 でエンコードできます。相手はこのように鍵を再構成でき、

  SecretKey key = new SecretKeySpec(keyBytes, "AES");

昨日、Sun の AES の例に関する別の質問に答えました。ここで著者は混乱した。彼は両方のステップを同時に行いました。

多くの場合、パスワードをシークレットとして使用し、パスワードからキーを生成すると、人間が覚えやすくなります。これは、PBE (パスワードベースの暗号化) と呼ばれます。以下は、キーを生成するために使用するコードです。

   public static SecretKey getAesKey(char[] password, int keyLength)
   throws GeneralSecurityException {

  int count = 128; // Iteration count
  byte[] salt;
  try {
   salt = "This is a fixed salt string".getBytes("UTF-8");
  } catch (UnsupportedEncodingException e) {
   throw new IllegalStateException("No UTF-8");
  }
  PBEKeySpec keySpec = new PBEKeySpec(password, salt, count, keyLength);
  SecretKeyFactory skf = SecretKeyFactory
    .getInstance("PBKDF2WithHmacSHA1");
  SecretKey pbeKey = skf.generateSecret(keySpec);
  byte[] raw = pbeKey.getEncoded();
  return new SecretKeySpec(raw, "AES");
 }

コードに対するもう 1 つの推奨事項として、毎回異なるランダム IV を使用すると、より安全になります。IV は秘密にする必要がないため、暗号文の先頭に追加できます。

于 2009-11-20T13:11:53.197 に答える
0

を呼び出してキーを取得してみてくださいkey.getEncoded()。これはバイト配列を返します。次に、Base64 ユーティリティ ( apache-commons codecなど) を使用して、バイト配列を文字列に変換できます。

ただし、暗号化されたファイルと復号化キーを誰かに送信することは、セキュリティの観点から侵害された行為であることに注意してください.

于 2009-11-20T08:23:29.553 に答える