使用TDCP_rijndael AES / CBC / NoPadding算法在DelphiXE7中加密并在Java中解密

时间:2017-09-26 07:50:48

标签: java delphi aes

我有问题。我想在Delphi程序中加密文本并在java中解密它。我使用AES / CBC / NoPadding来做到这一点,但java程序不能很好地解密文本。 下一步是使用PKCS5Padding,所以有人可以回答这个问题,这将是非常棒的!

德尔福代码:

var
    Cipher: TDCP_rijndael;
    Key: string;
    DataIn, DataOut: System.TArray<System.Byte>; 
begin
    Key := '0123456789012345';

    DataIn := nil;
    DataIn := TEncoding.UTF8.getbytes('SakisSakisSakisa');

    DataOut := nil;
    SetLength(DataOut, high(DataIn) + 1);
    Cipher := TDCP_rijndael.create(nil);
    Cipher.Algorithm := 'AES';
    Cipher.Init(Key[1], 128, nil);
    Cipher.EncryptCBC(DataIn[0], DataOut[0], high(DataIn) + 1);
    Cipher.Free;

    With TMemoryStream.create do begin
      Write(DataOut[0], length(DataOut));
      SaveToFile('c:\temp\encryption\sakisEnc.txt');
      Free;
    end;

DataIn具有以下字节: 83,97,107,105,115,83,97,107,105,115,83,97,107,105,115,97 此代码生成具有以下字节的加密字节数组DataOut: 3,207,105,252,118,38,28,145,89,77,107,8,181,205,190,165

现在是Java代码:

Path path = null;
String encryptionKey = null;
Cipher cipher = null;
SecretKeySpec key = null;
byte[] enc1;


path = FileSystems.getDefault().getPath("c:\\temp\\encryption\\SakisEnc.txt", "");
cipherText = Files.readAllBytes(path);

encryptionKey = "0123456789012345";   
cipher = Cipher.getInstance("AES/CBC/NoPadding");   
key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(encryptionKey.getBytes()));
dec1 = cipher.doFinal(cipherText);

dec1字节数组应该具有与Delphi DataIn代码相同的字节 83,97,107,105,115,83,97,107,105,115,83,97,107,105,115,97 但它包含其他内容。

我真的无法理解我做错了什么..... Thanx提前!

2 个答案:

答案 0 :(得分:1)

明显的区别在于你的钥匙。在您的Delphi代码中,您使用UTF-16编码密钥,但在Java代码中,您使用UTF-8编码密钥。

在Java代码中,库强制您将字节作为键传递。不幸的是,Delphi库更加宽松,让你陷入传递字符串的愚蠢行为。

我会将以下内容用于您的Delphi代码:

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpClientModule, HttpClient} from '@angular/common/http';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {AppComponent} from './app';

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}

@NgModule({
    imports: [
        BrowserModule,
        HttpClientModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: HttpLoaderFactory,
                deps: [HttpClient]
            }
        })
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

然后将var Key: TBytes; .... Key := TEncoding.UTF8.GetBytes('0123456789012345'); 传递给Key[0]

答案 1 :(得分:0)

在尝试之后,阅读,测试我做得好!

德尔福代码:

var
  Cipher: TDCP_rijndael;
  Key: System.TArray<System.Byte>;
  DataIn, DataOut, iv: System.TArray<System.Byte>; // array of byte;

  j: integer;
  i :integer;
  k :integer;
  s: string;

  sText :AnsiString;
  sTextLen :integer;
  paddingByte :string;
begin
  Key := TEncoding.UTF8.getbytes('0123456789012345');
  Iv := TEncoding.UTF8.getbytes('0123456789012345');

  DataIn := TEncoding.UTF8.getBytes(memo1.Text);
  //PKCS5Padding
  sTextLen := high(DataIn) + 1;
  i := 16 - (sTextLen mod 16);
  if i <= 16 then begin
    k := high(DataIn) + 1;
    setLength(DataIn, sTextLen + i);
    for j := k to high(DataIn) do begin
      DataIn[j] := i;
    end;
  end;

  //Encrypt.
  DataOut := nil;
  SetLength(DataOut, high(DataIn) + 1);
  Cipher := TDCP_rijndael.create(nil);
  Cipher.Algorithm := 'AES';
  Cipher.Init(Key[0], length(Key) * 8, Iv);
  Cipher.EncryptCBC(DataIn[0], DataOut[0], high(DataIn) + 1);
  Cipher.Free;

  //Save to file
  With TMemoryStream.create do begin
    Write(DataOut[0], length(DataOut));
    SaveToFile('c:\temp\encryption\sakisEnc.txt');
    Free;
  end;

Java代码: 在java代码中,delphis的Iv与加密密钥相同。所以我将encryptionKey传递给:new IvParameterSpec(encryptionKey.getBytes(&#34; UTF-8&#34;))

String encryptionKey = null;
Cipher cipher = null;
SecretKeySpec key = null;
byte[] enc1;
byte[] dec1;

path = FileSystems.getDefault().getPath("c:\\temp\\encryption\\SakisEnc.txt", "");
cipherText = Files.readAllBytes(path);

encryptionKey = "0123456789012345";
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") ;
key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(encryptionKey.getBytes("UTF-8")));
dec1 = cipher.doFinal(cipherText);