私は税のウェブサイトで正常に復号化されたAES暗号化を行うためにOpenSSLのコードの下に使用しています
openssl rand 48 > 48byterandomvalue.bin
hexdump /bare 48byterandomvalue.bin > 48byterandomvalue.txt
set /a counter=0
for /f "tokens=* delims= " %%i in (48byterandomvalue.txt) do (
set /a counter=!counter!+1
set var=%%i
if "!counter!"=="1" (set aes1=%%i)
if "!counter!"=="2" (set aes2=%%i)
if "!counter!"=="3" (set iv=%%i)
)
set result1=%aes1:~0,50%
set result1=%result1: =%
set result2=%aes2:~0,50%
set result2=%result2: =%
set aeskey=%result1%%result2%
set initvector=%iv:~0,50%
set initvector=%initvector: =%
openssl aes-256-cbc -e -in PAYLOAD.zip -out PAYLOAD -K %aeskey% -iv %initvector%
openssl rsautl -encrypt -certin -inkey test_public.cer -in
48byterandomvalue.bin -out 000000.00000.TA.840_Key
しかし、私が使用して私は、移行の一環として、Javaでこの同じことをやってみたかっ持つjavax.cryptoとjava.securityライブラリが、私は税のウェブサイト上のファイルをアップロードする際に復号化が失敗しています
//creating the random AES-256 secret key
SecureRandom srandom = new SecureRandom();
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();
byte[] aesKeyb = secretKey.getEncoded();
//creating the initialization vector
byte[] iv = new byte[128/8];
srandom.nextBytes(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);
byte[] encoded = Files.readAllBytes(Paths.get(filePath));
str = new String(encoded, StandardCharsets.US_ASCII);
//fetching the Public Key from certificate
FileInputStream fin = new FileInputStream("test_public.cer");
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
//encrypting the AES Key with Public Key
Cipher RSACipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
RSACipher.init(Cipher.ENCRYPT_MODE, pk);
byte[] RSAEncrypted = RSACipher.doFinal(aesKeyb);
FileOutputStream out = new FileOutputStream("000000.00000.TA.840_Key");
out.write(RSAEncrypted);
out.write(iv);
out.close();
また、Javaで生成されたAESキーは、OpenSSLを経由して生成されたものとは異なります。あなたたちは助けを喜ばせることができます。
EDIT 1:以下AES Encrpytionためのコードが使用されます。
Cipher AESCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
AESCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
byte[] AESEncrypted = AESCipher.doFinal(str.getBytes("UTF-8"));
String encryptedStr = new String(AESEncrypted);
RSAとスクリプトとJavaコードの暗号化が異なることデータ:
このスクリプトは、ファイル内のランダムな48バイト・シーケンスおよび格納を生成します
48byterandomvalue.bin
。最初の32のバイトは、AES鍵、IVなどの最後の16のバイトとして用いられます。キーとIVは、ファイルの暗号化に使用されているPAYLOAD.zip
CBCモードでAES-256を、ファイルとして保存しますPAYLOAD
。ファイルには、48byterandomvalue.bin
RSAで暗号化し、ファイルとして保存されます000000.00000.TA.840_Key
。Javaのコードでは、ランダムな32バイトAES鍵とランダムの16バイトIVが生成されます。どちらも、CBCモードでAES-256で暗号化を実行するために使用されています。AESキーは、RSAで暗号化された暗号化されていないIVと連結し、その結果をファイルに保存されています
000000.00000.TA.840_Key
。ファイルの内容は
000000.00000.TA.840_Key
、スクリプトとJavaコードのために異なっています。Javaのコードを生成するためにfile 000000.00000.TA.840_Key
、スクリプトロジックで、暗号化されていない AESキーは暗号化されていないIVと連結しなければならず、この結果は、RSAで暗号化する必要があります。... //byte[] aesKeyb byte-array with random 32-bytes key //byte[] iv byte-array with random 16-bytes iv byte[] key_iv = new byte[aesKeyb.length + iv.length]; System.arraycopy(aesKeyb, 0, key_iv, 0, aesKeyb.length); System.arraycopy(iv, 0, key_iv, aesKeyb.length, iv.length); ... byte[] RSAEncrypted = RSACipher.doFinal(key_iv); FileOutputStream out = new FileOutputStream("000000.00000.TA.840_Key"); out.write(RSAEncrypted); out.close(); ...
注:IVは秘密である必要はありませんので、暗号化する必要はありません。暗号化は、Javaコードでスクリプトの結果を生成するのに必要なだけです。
もう一つの問題は、文字列に任意のバイナリデータの変換に関するものです。破損したデータへのこの一般的リードエンコーディングが不適切である場合(例えばASCIIまたはUTF8)。故に
... byte[] encoded = Files.readAllBytes(Paths.get(filePath)); str = new String(encoded, StandardCharsets.US_ASCII); // Doesn't work: ASCII (7-bit) unsuitable for arbitrary bytes, * ... byte[] AESEncrypted = AESCipher.doFinal(str.getBytes("UTF-8")); // Doesn't work: UTF-8 unsuitable for arbitrary bytes and additionally different from * String encryptedStr = new String(AESEncrypted); // Doesn't work: UTF-8 unsuitable for arbitrary bytes ...
に置き換える必要があります
... byte[] encoded = Files.readAllBytes(Paths.get(filePath)); ... byte[] AESEncrypted = AESCipher.doFinal(encoded); FileOutputStream out = new FileOutputStream("PAYLOAD"); out.write(AESEncrypted); out.close(); ...
文字列内の任意のデータを格納するための適切な符号化は、例えば、Base64であるが、Base64で符号化がいずれかのスクリプトで使用されていないため、これは、この場合には必要ではありません。
これらの変更を試してみてください。その他の問題が発生した場合、それは、AES暗号化、RSA暗号化、およびテストするために最善のだろう
key_iv
世代を個別に。これは、分離株のバグにそれが容易になります。