باسلام مجدد من کد های زیر را برای تولید RSA Sign استفاده کردم
کد HTML:
const
LIBEAY_DLL_NAME = 'libeay32.dll';
// These aren't defined in the original libeay32.pas file
procedure EVP_MD_CTX_init(ctx: PEVP_MD_CTX); cdecl; external LIBEAY_DLL_NAME;
function EVP_MD_CTX_cleanup(ctx: PEVP_MD_CTX): integer; cdecl; external LIBEAY_DLL_NAME;
procedure InitSSL;
begin
OpenSSL_add_all_algorithms;
OpenSSL_add_all_ciphers;
OpenSSL_add_all_digests;
ERR_load_crypto_strings;
// Seed the pseudo-random number generator
// This should be something a little more "random"!
RAND_load_file('c:\windows\paint.exe', 512);
end;
procedure FinalizeSSL;
begin
EVP_cleanup;
end;
function GetSSLErrorMessage: string;
const
BUFF_SIZE = 128; // OpenSSL docs state should be >= 120 bytes
var
err: TBytes;
begin
SetLength(err, BUFF_SIZE);
ERR_error_string(ERR_get_error, @err[0]);
result := string(err);
end;
function RSALoadPrivateKey(const AFileName, APassPhrase: string): PRSA;
var
bp: pBIO;
fn, pp: PAnsiChar;
pk: PRSA;
begin
fn := PAnsiChar(AnsiString(AFileName));
pp := PAnsiChar(AnsiString(APassPhrase));
bp := BIO_new(BIO_s_file());
BIO_read_filename(bp, fn);
pk := nil;
result := PEM_read_bio_RSAPrivateKey(bp, pk, nil, pp);
if result = nil then
raise Exception.Create('Private key failure.' + GetSSLErrorMessage);
end;
function LoadPrivateKey(const AFileName, APass: string): PEVP_PKEY;
var
rkey: PRSA;
begin
rkey := RSALoadPrivateKey(AFileName, APass);
result := EVP_PKEY_new;
EVP_PKEY_assign(result, EVP_PKEY_RSA, rkey);
end;
procedure CleanUpKey(AKey: PEVP_PKEY);
begin
if (AKey <> nil) then
begin
EVP_PKEY_free(AKey);
end;
end;
function EVPSign(ASource: TBytes; const APrivateKey: PEVP_PKEY): TBytes;
var
keysize: integer;
ks: cardinal;
ctx: EVP_MD_CTX;
begin
keysize := EVP_PKEY_size(APrivateKey);
SetLength(result, keysize);
EVP_MD_CTX_init(@ctx);
try
EVP_SignInit(@ctx, EVP_sha1);
EVP_SignUpdate(@ctx, @ASource[0], Length(ASource));
EVP_SignFinal(@ctx, @result[0], ks, APrivateKey);
SetLength(result, ks);
finally
EVP_MD_CTX_cleanup(@ctx);
end;
end;
function Base64EncodeBytes(Input: TBytes): UTF8String;
begin
result := utf8string(
TNetEncoding.Base64.EncodeBytesToString(Input, Length(Input)));
end;
function SignStringToBase64(AText: utf8string): string;
var
key: PEVP_PKEY;
src, enc: TBytes;
begin
//AText:= UTF8String(AText);
InitSSL;
try
key := LoadPrivateKey('d:\wsus\pvkey.pem', '');
try
SetLength(src, Length(AText));
CopyMemory(@src[0], @AText, Length(AText));
enc := EVPSign(src, key);
result := string(Base64EncodeBytes(enc));
finally
CleanUpKey(key);
end;
finally
FinalizeSSL;
end;
end;
الان اتفاقی که میفته اینست که امضا تولید شده با امضا ایجاد شده توسط یک برنامه php مثل هم نیست و تفاوت دارد فرضا اگه رشته ورودی برای هر دو برنامه Delphi, PHP به صورت زیر باشد:
کد HTML:
{"UserName":"Service","DepositNumber":"999999","Timestamp":"2019\/04\/16 22:07:41:105"}
و PrivateKey هم به صورت زیر باشد
کد HTML:
-----BEGIN RSA PRIVATE KEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCUHbx9tht5pHWSnGoexgb+S+2sNvQeeqSdDmkopgAkBhW9NGE2q76JAN/uLfxnoDlnv6EfR78hCaEtYE66QykpsJsRimPF1wxkh4tMAi2EYw2Um8WhkGc9cPMMatWn0E4XK3x68CYkEifPigLdgV48hzRk6ATsQ77Ux90k0FEBLWvwHrvY42QaL8s6AP+oZadUbGsFX3y9bVqc74W7vFsmdqbfxvEdZmGBS7JC9BcbsZ6+i16PRmjb5/qExIHSKO65ZG7SZy+DEiVDcgz8UelDF3BRMmik/lP646fB+WySyBejJkNVXx6YH09EuQ04vaTnM2s7IlP0vc6/7R7AgMBAAECggEAIlrXWo0/yDI2NyBimOqzuo4f/Z7tdphZ0DgEejIuvCxRJIaet99npPIJPenWiextdfSezyPWwyJGaqm4SXXUGLbvgM1RMU4A27i+YJ0UtMR8cMaXMA5kx+OyGlcC6DzpEfl0Zj9Q9VkKXhixT4ZaQXZJhKkbuBy2t3qNEAxSsnYPAQzY5lqTIkz04ZP3ru1fOyfoRO1W6kSoBb3NvIjtUwm9cIdGggoMRQqmUEQAg/u3jFr0A0HAQW0TPL2SqR3wNxnajJ41yJmAmKWgenVsTnyCWsVkTgkSoJnj1XAi6Jv4WcmRqS6cllnrK1GLfJyLOOWBAanKJi1FeEfk3ewOoQKBgQDImPYrwIEBjUGuCITWa2LPYre8lYgMtLUOw0Sn5jS8X2ipnbpMl9LtQwhTqyHjQTYUi0C7xCeWy+/GyAIzzAQviwfQvalFTWOofuipA0d3CdQjX9XQLU6XrIXoNl/R09/z7LG85r4br6DdaVKpWTdDyFjC9qkv8AAWW4mQeR4HEQKBgQC9BiKqJeOU2mRxTChlqtn2rQE4RoKYSqmjIlKiVbQJg84D3fNkkDfbDpKWJ4JUCRo73/UygYIL24gJe+iS4/9Ee4LUdpiHqYtUUm9n26QVUCkm6ODQckX6BVZ+GyVwfcYQsi7PqKQSNRfoOExg4VkcmiIO+ynhilfQ/C3Uh7J6ywKBgQCaHzQcf4Ze29oXzcHKQK2la1KCGV1zbbAizJLGcZAZHzD6CQ6nZIsR8kvGhRi/U04q0KcG3PoR2VS7pNZUV67rnGV/0wjoD0K/peo6WSOiaTHNkAdmMDlPPaWQuZ47SA+siTIyUhLEkNcG5rI1HS/h61+PRBbPlxVqGCCEmRoiEQKBgFVwi4SrIaZr3NDVYsEpq+HzK0T7ohYiUXE6l21nHbzbRei7j0OaaJTsjleuvhssDh6YSaWtolGnxmK7DlIvGngi9+z/Oky/1wmjRVYFkrJLjH5Y7x1pObYcaY8QyCiDwV5UnBIjIR5Vv1uo7uUvlu71wIVTBAg9VxpQkoqpV4RnAoGAcDJqcU+NNeAfwjPIlpglzxoUUvQAA/moQB3xmS0XP6U74X5Hri70DGZ96Mjj8d1oJSTG3NKRfmaO/ZF+ggKcDpYFKpOSxrJPMbxgQu381OW4ctm1oCUdFVfYE6hORA75eYrYaKTu4itjjp+7hucJ8cR0zEQ9XGxIUkpl+AEcxgc=-----END RSA PRIVATE KEY-----
متن sign برای php بصورت
کد HTML:
M7dN2sCn2NG3TWPA0kk8LiQTfhaZljpSfctuCpUoKTAcWzEwOtweOKsHRqeKjUoBaU1QpMMWx+Peq0iogv01ASBSDqe8r7EciShX3K36dJa8n5Y7x+C7jK10nk2Uw5HUYILnZCr0lRjyL8ciI+e4o9YD0rD2tF+VpeIxzi0PBMmdRxy1fKjSK/9bMx1b8j/j2Axmln7Ix3PJ0RyGDGxz/fs8Ydz4/X8qsBBAr0H9YkVf5ptPMB3aYRJQIFWz6Yc4PSpU/tlNGVJUuQOvby/1KqfHmJz1UMjCFSt80GRtkWsDes/2nQ8FmFUhEgdACUL70yMsSdv4DoO14UYPqjEkyg==
و برای دلفی
کد HTML:
EDYxEkFWnct1hrnUNL/Jfcf5Hp2DORS6h6AkUemrle8WEbdMtezrE+V8Uq1HSbL7Gk2QPqhn2mJz
YQ4T2DhqlJx2TlDUT6ZhxJXKjr1E7wBorSLI4KsHdfSBPLJrmEjXYkpNPImE5zy7vsZte7Vt95pl
GwEERvySC1FoE8YvmV7S3RkceGAuJ495ctCg+ul6lbi/JolKPInX76tlsnQoUs8g6Va4SJ0l6vmM
o7Ti8j+5un4v9eUJkNVbH85yK0pLZJCToP9/TP8q6T0t2k5wbX6YWw3tsRYlhiCXvY1gSTpuQDte
m3zstF0wG/FLeA5vdibXYUeFGi0hZpqWXAQG4Q==
میشود. چگونه مشکل را حل کنم. اصلا نمیدونم مشکل کجاست.
لطفا دوستانیکه اطلاع دارند راهنمایی بفرمایند