# Native Code > برنامه نویسی در Delphi > توسعه نرم افزارهای تحت شبکه > سوال: شیوه ی استفاده از رمزنگاری RSA -- RSA Signing

## K.Mohammadreza

باسلام 
من برای استفاده از یک برنامه تحت شبکه باید پیامهای بین سرور و برنامه را Encrypt کنم. در واقع یک وب سرویس Soap هست که هر تابع شامل 2 پارامتر می باشد. پارامتر Request و پارامتر Signature 

پارامتر Request شامل اطلاعات مورد نیاز تابع در قالب یک رشته JSON و
پارامتر Signature شامل امضا دیجیتال رشته ی Request  با کلید خصوصی RSA

من کلید خصوصی را در قالب فایل XML , PEM دارم در ابتدا باید رشته ی JSON درخواست با الگوریتم SHA-1 به صورت هَش در بیاد و هَش بدست آمده توسط کلید خصوصی امضا (Encrypt) و در نهایت نتبجه بصورت Base64 در پارامتر Signature ارسال شود.

چگونه در دلفی قسمت دوم را پیاده سازی کنم؟ نسخه دلفی مورد استفاده Delphi XE8 می باشد.

باسپاس

----------


## K.Mohammadreza

آیا rsa crypto service provider در دلفی وجود داره؟

----------


## hp1361

> آیا rsa crypto service provider در دلفی وجود داره؟


سلام

از این کامپوننت TMS Cryptography Pack و یا این کامپوننت IP*Works! Encrypt میتونید برای Encrypt  کردن استفاده کنید

هردوشون الگوریتم RSA رو پشتیبانی میکنند

موفق باشیم

----------


## K.Mohammadreza

باسلام مجدد من کد های زیر را برای تولید RSA Sign استفاده کردم


```
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 به صورت زیر باشد:


```
{"UserName":"Service","DepositNumber":"999999","Timestamp":"2019\/04\/16 22:07:41:105"}
```

و PrivateKey  هم به صورت زیر باشد


```
-----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 بصورت


```
M7dN2sCn2NG3TWPA0kk8LiQTfhaZljpSfctuCpUoKTAcWzEwOtweOKsHRqeKjUoBaU1QpMMWx+Peq0iogv01ASBSDqe8r7EciShX3K36dJa8n5Y7x+C7jK10nk2Uw5HUYILnZCr0lRjyL8ciI+e4o9YD0rD2tF+VpeIxzi0PBMmdRxy1fKjSK/9bMx1b8j/j2Axmln7Ix3PJ0RyGDGxz/fs8Ydz4/X8qsBBAr0H9YkVf5ptPMB3aYRJQIFWz6Yc4PSpU/tlNGVJUuQOvby/1KqfHmJz1UMjCFSt80GRtkWsDes/2nQ8FmFUhEgdACUL70yMsSdv4DoO14UYPqjEkyg==
```

و برای دلفی 


```
EDYxEkFWnct1hrnUNL/Jfcf5Hp2DORS6h6AkUemrle8WEbdMtezrE+V8Uq1HSbL7Gk2QPqhn2mJz
YQ4T2DhqlJx2TlDUT6ZhxJXKjr1E7wBorSLI4KsHdfSBPLJrmEjXYkpNPImE5zy7vsZte7Vt95pl
GwEERvySC1FoE8YvmV7S3RkceGAuJ495ctCg+ul6lbi/JolKPInX76tlsnQoUs8g6Va4SJ0l6vmM
o7Ti8j+5un4v9eUJkNVbH85yK0pLZJCToP9/TP8q6T0t2k5wbX6YWw3tsRYlhiCXvY1gSTpuQDte
m3zstF0wG/FLeA5vdibXYUeFGi0hZpqWXAQG4Q==
```

میشود. چگونه مشکل را حل کنم. اصلا نمیدونم مشکل کجاست. 
لطفا دوستانیکه اطلاع دارند راهنمایی بفرمایند

----------


## K.Mohammadreza

خدا را شکر بدون استفاده از  کامپوننت های جانبی و با دستورات خود دلفی موفق شدم به نتیجه دلخواه برسم. از دوستانیکه جواب دادن تشکر میکنم ولی خیلی ساده تر از اون چیزی بود که فکر میکردم

----------


## BORHAN TEC

با سلام.
همچنین پکیج LockBox3 هم از RSA پشتیبانی میکند که به طور رایگان هم هست. این محصول قبلاً توسط TurboPower توسعه داده میشد ولی اکنون به صورت رایگان و کدباز در اختیار همه میباشد: 
https://github.com/TurboPack/LockBox3
موفق باشید ...

----------


## دلفــي

سلام
من هم دقیقا همین مشکل رو دارم
لطفا راه حلی که پیدا کردید رو بگید منم استفاده کنم
ممنون

----------


## دلفــي

> خدا را شکر بدون استفاده از  کامپوننت های جانبی و با دستورات خود دلفی موفق شدم به نتیجه دلخواه برسم. از دوستانیکه جواب دادن تشکر میکنم ولی خیلی ساده تر از اون چیزی بود که فکر میکردم


از دوستان کسی نمیدونه ایشون از چه روشی استفاده کردن ؟

----------

