1

我正在使用带有 LockBox 3 的 Delphi XE8 构建一个 RESTful 服务器进行加密。我使用 AES 加密数据 (JSON) 并将其发送到 Adroid 设备 - 客户端。

如果我将加密数据发送给客户端并且客户端知道加密密钥,那么他如何在不知道 IV 的情况下解密数据,因为它由 LB3 内部自动管理?

我正在使用德尔福 XE8

第一:我安装了上一个版本的 LockBox。

第二:没有关于如何设置 IV 的文档。

我设法得到了IV(密文的前8个字节):

function TAESEnrypt.EncryptAES_String(const str: string): string;
var
 Codec1: TCodec;
 CryptographicLibrary1: TCryptographicLibrary;
 bt:TByteArray;
 m:TMemoryStream;
 AEncoding: TEncoding;
 pCipher: TBytes;
 bytes: TBytes;
 text: string;
 Encoding: TEncoding;
 iv:TBytes;
 cipher:TBytes;
 i:integer;
begin
  Result:='';
  KeyHex:='';
  KeyBin:=TMemoryStream.Create;
  Codec1 := TCodec.Create( nil);
  CryptographicLibrary1 := TCryptographicLibrary.Create( nil);
  Codec1.CryptoLibrary  := CryptographicLibrary1;
  Codec1.StreamCipherId := BlockCipher_ProgId;
  Codec1.BlockCipherId  := 'native.AES-128';
  Codec1.ChainModeId    := CBC_ProgId;
  Codec1.Password := Password;
  Codec1.EncryptString(str, CipherText, TEncoding.UTF8);
  Result:=CipherText;
  Codec1.Key.SaveToStream(KeyBin);
  Codec1.Free;
  CryptographicLibrary1.Free;
  //key ==> HEX
  KeyBin.Position:=0;
  SetLength(KeyHex,KeyBin.Size*2);
  SetLength(bt, KeyBin.Size);
  KeyBin.Read(bt[0],KeyBin.Size);
  KeyBin.Position:=0;
  BinToHex(bt[0],pchar(KeyHex),KeyBin.Size);
  //key ==> base64
  Key64:=TNetEncoding.Base64.EncodeBytesToString(bt);
  //
  {
   Ciphertext = Base64
   IV ==> Extract the first 8 bytes (64 bits)
   1. Base64 ==> Binary
   2. get IV
   3. Binary ==> Base64 (Ciphertext)
   4. Binary ==> Base64 (IV)
   5. Binary ==> HEX (Ciphertext)
   6. Binary ==> HEX (IV)
  }
  bytes := TNetEncoding.Base64.DecodeStringToBytes(CipherText);//result => binary data
  iv:=Copy(bytes,0,8);//get first 8 bytes (iv) => binary data
  cipher:=Copy(bytes,8,Length(bytes)-8);//the rest is the encrypted data => binary data
  //Bin => base64
  iv64:=TNetEncoding.Base64.EncodeBytesToString(iv);
  cipher64:=TNetEncoding.Base64.EncodeBytesToString(cipher);
  //Bin => HEX
  SetLength(ivHex,Length(iv)*2);
  BinToHex(iv[0],pchar(ivHex),Length(iv));
  SetLength(CipherHex,Length(cipher));
  BinToHex(Cipher[0],pchar(CipherHex),Length(Cipher));
end;

例如(128):

iv_64 : P7NJIfhws2k=
iv_hex: 3FB34921F870B369
cipher_64 : 5UvFMw==
cipher_hex: E54B
Key_64 : /dn9yyUOTWobOQx1A+ZfAg==
Key_hex: FDD9FDCB250E4D6A1B390C7503E65F02

在客户端(Android)上,我收到错误“Bad base 64”或“最后一个块在解密中不完整”,这是我的代码(仅用于测试):

[我用零完成IV]

            byte[] out=new byte[16];
            byte[] zero="00000000".getBytes();

            byte[] ivBytes; byte[] keyBytes; byte[] textBytes;
            ivBytes=Base64.decode("9pdfnd4JvpI=".getBytes("UTF-8"),Base64.DEFAULT);
            System.arraycopy(ivBytes,0,out,0,ivBytes.length);
            System.arraycopy(zero,0,out,ivBytes.length,zero.length);

            keyBytes=Base64.decode("/dn9yyUOTWobOQx1A+ZfAg==".getBytes("UTF-8"),Base64.DEFAULT);
            textBytes=Base64.decode("+JnDcw==".getBytes("UTF-8"),Base64.DEFAULT);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(out);
            SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING");
            cipher.init(Cipher.DECRYPT_MODE, newKey,ivSpec);
            byte[] decodedBytes = cipher.doFinal(textBytes);
            String plain=new String(decodedBytes,"UTF-8");

当我在 Android 中运行它时,我得到:“解​​密中的最后一个块不完整”,当我从 getBytes() 中删除“UTF-8”时,我得到“bad base-64”,我不知道如何解决它,任何想法?

4

0 回答 0