- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 PHP (openssl_encrypt/'aes-256-cbc') 中加密文本,然后尝试在 Delphi 7 (DCPCrypt/TDCP_rijndael) 中解密它。
PHP 脚本文件以ANSI 编码保存,希望传输的字符串(其REST API Web 服务)与Delphi 兼容。
但是 Delphi 解密产生了错误的结果,我猜测代码中有问题。如果您能看一下,并在 Delphi 方面发现我的错误,我将不胜感激:
PHP代码:
function encrypt($key, $payload) {
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
$encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
return base64_encode($encrypted . '::' . $iv);
}
function decrypt($key, $garble) {
list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
}
德尔福代码:
var
DCP_rijndael: TDCP_rijndael;
const
cPASSWORD = 'myownpassword';
function Decrypt(AStr: string): string;
var
d, s, iv: String;
p: Integer;
begin
d := Base64DecodeStr(AStr);
p := Pos('::', d);
s := Copy(d, 1, p - 1);
iv := Copy(d, p + 2, Length(s));
DCP_rijndael.SetIV(iv);
Result := DCP_rijndael.DecryptString(s);
end;
initialization
DCP_rijndael := TDCP_rijndael.Create(nil);
DCP_rijndael.Algorithm := 'Rijndael';
DCP_rijndael.CipherMode := cmCBC;
//DCP_rijndael.BlockSize := 128; {tried various values with no luck!}
//DCP_rijndael.MaxKeySize := 256;{tried various values with no luck!}
DCP_rijndael.Init(cPASSWORD, 256, nil);
finalization
DCP_rijndael.Free;
..有一个紧迫的项目截止日期,我坚持这个..将非常感谢帮助解决问题。蒂亚!
最佳答案
需要了解的基础知识
<?php
// This file's output should not be interpreted as HTML
header( 'Content-type: text/plain' );
// Do not use the same literals again and again
define( 'CIPHER', 'aes-128-cbc' ); // Which algorithm is used
define( 'GLUE', '::' ); // How to concatenate data and IV
function encrypt( $key, $plain ) {
// Initialization vector comes in binary. If we want to carry that
// thru text-like worlds then we should convert it to Base64 later.
$iv= openssl_random_pseudo_bytes( openssl_cipher_iv_length( CIPHER ) );
echo "\n iv=\t\t(binary as hex)\t". bin2hex( $iv ). "\tlength=". strlen( $iv );
// By default OpenSSL already returns Base64, but it could be changed
// to binary with the 4th parameter, if we want.
$encryptedData= openssl_encrypt( $plain, CIPHER, $key, 0, $iv );
echo "\n encrypted=\t(Base64)\t". $encryptedData;
// The encrypted data already came in Base64 - no need to encode it
// again in Base64. Just concatenate it with the initialization
// vector, which is the only part that should also be encoded to
// Base64. And now we have a 7bit-safe ASCII text, which could be
// easily inserted into e-mails.
return $encryptedData. GLUE. base64_encode( $iv ). GLUE. strlen( $plain );
}
function decrypt( $key, $allinone ) {
// The "glue" must be a sequence that would never occur in Base64.
// If everything works as expected we get an array with exactly three
// elements: first is data, second is IV, third is size.
$aParts= explode( GLUE, $allinone, 3 );
// OpenSSL expects Base64 by default as input - don't decode it!
$data= $aParts[0];
echo "\n data=\t\t(Base64)\t". $data;
// The initialization vector was encoded in Base64 by us earlier and
// now needs to be decoded to its binary form. Should size 16 bytes.
$iv= base64_decode( $aParts[1] );
echo "\n iv=\t\t(binary as hex)\t". bin2hex( $iv ). "\tlength=". strlen( $iv );
return openssl_decrypt( $data, CIPHER, $key, 0, $iv );
}
// Keep in mind that you DON'T encrypt and decrypt "TEXT" - you
// operate on binary data. Likewise make sure you fully understood
// this by choosing only ASCII before advancing into the world of
// different text encodings. Never mix encryption with "Strings" -
// only operate on it as if it would be naked bytes that make no sense!
$plain= 'AbCdEfGhIjKlMnOpQrStUvWxYz';
$key= '1234567890123456';
echo "Parameters:
plain=\t\t(binary)\t$plain\tlength=". strlen( $plain ). "
key=\t\t(binary)\t$key\tlength=". strlen( $key ). "
";
echo "\nEncryption:";
$en= encrypt( $key, $plain );
echo "\n allinone=\t(ASCII)\t\t". $en. "\n";
echo "\nDecryption:";
$de= decrypt( $key, $en );
echo "\n decrypted=\t(binary)\t". $de;
如果选择
9e8e5d5ab909d93c991fd604b98f4f50
的
initialization vector(
hexadecimal 表示其 16 字节长度),则加密应生成
9NC0HhAxFZLuF/omOcidfDQnczlczTS1nIZkNPOlQZk=::no5dWrkJ2TyZH9YEuY9PUA==::26
的一体式文本,其中第一部分是 Base64 中的加密数据,第二部分是 Base64 中的初始化向量,第三部分确保我们的纯(文本)输入的长度。使用该长文本,您应该能够将其解码回
AbCdEfGhIjKlMnOpQrStUvWxYz
的纯文本(文本)(长度为 26 字节)。
String
在其他版本中必须始终被视为
AnsiString
,否则最终会不是字节安全的东西。
uses
DecCipher, DecFmt;
const // The same glue for concatenating all 3 parts
GLUE= '::';
var
c: TDecCipher; // Successfully tested with DEC 5.2 on Delphi 7
sAllInOne, // All 3 parts in a 7bit-safe ASCII text
sKey, // The binary key we have to provide
sIv, // Initialization vector, decoded from sAllInOne
sEncrypted, // Actual data to decrypt, decoded from sAllInOne
sPlain: AnsiString; // Decrypted binary we want to get
iPosGlue, // Next found glue token to cut one part off
iLength: Integer; // Plaintext length target, in bytes
begin
// What was output by the PHP script
sAllInOne:= '9NC0HhAxFZLuF/omOcidfDQnczlczTS1nIZkNPOlQZk=::no5dWrkJ2TyZH9YEuY9PUA==::26';
// Find next delimiter; Base64 will never have a '..' sequence
iPosGlue:= Pos( GLUE, sAllInOne );
sEncrypted:= Copy( sAllInOne, 1, iPosGlue- 1 ); // Still Base64
Delete( sAllInOne, 1, iPosGlue- 1+ Length( GLUE ) );
iPosGlue:= Pos( GLUE, sAllInOne );
sIv:= Copy( sAllInOne, 1, iPosGlue- 1 );
Delete( sAllInOne, 1, iPosGlue- 1+ Length( GLUE ) );
// What remains is the length of the original text, once decrypted. Why do we need it?
// Because the cipher/algorithm depends on fixed block sizes, so it is automatically
// padded to the next full length. Otherwise we end up with decryptions that will
// always have a few odd bytes at the end, if they aren't multiples of 16.
iLength:= StrToInt( sAllInOne );
// Keep in mind: this is treated as binary, not text!
sKey:= '1234567890123456';
// Decode Base64 back into binary
sEncrypted:= TFormat_MIME64.Decode( sEncrypted );
sIv:= TFormat_MIME64.Decode( sIv );
// Expect DEC 5.2 to only deal with AES-128-CBC, not 256.
c:= ValidCipher( DecCipher.TCipher_Rijndael ).Create;
try
c.Mode:= cmCBCx;
c.Init( sKey, sIv ); // Provide binary key and binary IV
SetLength( sPlain, Length( sEncrypted ) ); // By now the output length must match the input's
c.Decode( sEncrypted[1], sPlain[1], Length( sEncrypted ) );
SetLength( sPlain, iLength ); // Now cut it to the actual expected length
// We're done: sPlain should be 'AbCdEfGhIjKlMnOpQrStUvWxYz'
Writeln( sPlain );
finally
c.Free;
end;
end;
由于未使用 OpenSSL,我们需要自己处理块大小填充 - 如果您省略最后一个长度分配,您将看到有更多字节可以四舍五入到 32 字节的大小。
关于Delphi 7 - DCPCrypt - TDCP_rijndael - DecryptString - 如何使它工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65810276/
我在Windows 10中使用一些简单的Powershell代码遇到了这个奇怪的问题,我认为这可能是我做错了,但我不是Powershell的天才。 我有这个: $ix = [System.Net.Dn
var urlsearch = "http://192.168.10.113:8080/collective-intellegence/StoreClicks?userid=" + userId +
我有一个非常奇怪的问题,过去两天一直让我抓狂。 我有一个我试图控制的串行设备(LS 100 光度计)。使用设置了正确参数的终端(白蚁),我可以发送命令(“MES”),然后是定界符(CR LF),然后我
我目前正试图让无需注册的 COM 使用 Excel 作为客户端,使用 .NET dll 作为服务器。目前,我只是试图让概念验证工作,但遇到了麻烦。 显然,当我使用 Excel 时,我不能简单地使用与可
我开发了简单的 REST API - https://github.com/pavelpetrcz/MandaysFigu - 我的问题是在本地主机上,WildFly 16 服务器的应用程序运行正常。
我遇到了奇怪的情况 - 从 Django shell 创建一些 Mongoengine 对象是成功的,但是从 Django View 创建相同的对象看起来成功,但 MongoDB 中没有出现任何数据。
我是 flask 的新手,只编写了一个相当简单的网络应用程序——没有数据库,只是一个航类搜索 API 的前端。一切正常,但为了提高我的技能,我正在尝试使用应用程序工厂和蓝图重构我的代码。让它与 pus
我的谷歌分析 JavaScript 事件在开发者控制台中运行得很好。 但是当从外部 js 文件包含在页面上时,它们根本不起作用。由于某种原因。 例如; 下面的内容将在包含在控制台中时运行。但当包含在单
这是一本名为“Node.js 8 the Right Way”的书中的任务。你可以在下面看到它: 这是我的解决方案: 'use strict'; const zmq = require('zeromq
我正在阅读文本行,并创建其独特单词的列表(在将它们小写之后)。我可以使它与 flatMap 一起工作,但不能使它与 map 的“子”流一起工作。 flatMap 看起来更简洁和“更好”,但为什么 di
我正在编写一些 PowerShell 脚本来进行一些构建自动化。我发现 here echo $? 根据前面的语句返回真或假。我刚刚发现 echo 是 Write-Output 的别名。 写主机 $?
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我将一个工作 View Controller 类从另一个项目复制到一个新项目中。我无法在新项目中加载 View 。在旧项目中我使用了presentModalViewController。在新版本中,我
我对 javascript 很陌生,所以很难看出我哪里出错了。由于某种原因,我的功能无法正常工作。任何帮助,将不胜感激。我尝试在外部 js 文件、头部/主体中使用它们,但似乎没有任何效果。错误要么出在
我正在尝试学习Flutter中的复选框。 问题是,当我想在Scaffold(body :)中使用复选框时,它正在工作。但我想在不同的地方使用它,例如ListView中的项目。 return Cente
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我有一个组合框,其中包含一个项目,比如“a”。我想调用该组合框的 Action 监听器,仅在手动选择项目“a”完成时才调用。我也尝试过 ItemStateChanged,但它的工作原理与 Action
你能看一下照片吗?现在,一步前我执行了 this.interrupt()。您可以看到 this.isInterrupted() 为 false。我仔细观察——“这个”没有改变。它具有相同的 ID (1
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我正在尝试在我的网站上设置一个联系表单,当有人点击发送时,就会运行一个作业,并在该作业中向所有管理员用户发送通知。不过,我在失败的工作表中不断收到此错误: Illuminate\Database\El
我是一名优秀的程序员,十分优秀!