Piszę program C, który szyfruje (na podstawie klucza prywatnego) i odszyfrowuje (w oparciu o klucz publiczny) tekst. Próbuję to zrobić z biblioteką OpenSSL. Czy ktoś zna dobry tutorial, przewodnik szybkiego startu lub przykładowy kod? Nie znalazłem żadnego przyzwoitego w sieci.Szyfrowanie/odszyfrowywanie RSA
Odpowiedz
Oto przykład stworzyłem do szyfrowania plików za pomocą RSA do asymetrycznego algorytmu AES-128-CBC dla algorytmu symetrycznego, z funkcjami EVP OpenSSL:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <arpa/inet.h> /* For htonl() */
int do_evp_seal(FILE *rsa_pkey_file, FILE *in_file, FILE *out_file)
{
int retval = 0;
RSA *rsa_pkey = NULL;
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_CIPHER_CTX ctx;
unsigned char buffer[4096];
unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
size_t len;
int len_out;
unsigned char *ek = NULL;
int eklen;
uint32_t eklen_n;
unsigned char iv[EVP_MAX_IV_LENGTH];
if (!PEM_read_RSA_PUBKEY(rsa_pkey_file, &rsa_pkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Public Key File.\n");
ERR_print_errors_fp(stderr);
retval = 2;
goto out;
}
if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey))
{
fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
retval = 3;
goto out;
}
EVP_CIPHER_CTX_init(&ctx);
ek = malloc(EVP_PKEY_size(pkey));
if (!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &pkey, 1))
{
fprintf(stderr, "EVP_SealInit: failed.\n");
retval = 3;
goto out_free;
}
/* First we write out the encrypted key length, then the encrypted key,
* then the iv (the IV length is fixed by the cipher we have chosen).
*/
eklen_n = htonl(eklen);
if (fwrite(&eklen_n, sizeof eklen_n, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
if (fwrite(ek, eklen, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
/* Now we process the input file and write the encrypted data to the
* output file. */
while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0)
{
if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len))
{
fprintf(stderr, "EVP_SealUpdate: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
}
if (ferror(in_file))
{
perror("input file");
retval = 4;
goto out_free;
}
if (!EVP_SealFinal(&ctx, buffer_out, &len_out))
{
fprintf(stderr, "EVP_SealFinal: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
out_free:
EVP_PKEY_free(pkey);
free(ek);
out:
return retval;
}
int main(int argc, char *argv[])
{
FILE *rsa_pkey_file;
int rv;
if (argc < 2)
{
fprintf(stderr, "Usage: %s <PEM RSA Public Key File>\n", argv[0]);
exit(1);
}
rsa_pkey_file = fopen(argv[1], "rb");
if (!rsa_pkey_file)
{
perror(argv[1]);
fprintf(stderr, "Error loading PEM RSA Public Key File.\n");
exit(2);
}
rv = do_evp_seal(rsa_pkey_file, stdin, stdout);
fclose(rsa_pkey_file);
return rv;
}
i odpowiadająca przykład deszyfrowania:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <arpa/inet.h> /* For htonl() */
int do_evp_unseal(FILE *rsa_pkey_file, FILE *in_file, FILE *out_file)
{
int retval = 0;
RSA *rsa_pkey = NULL;
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_CIPHER_CTX ctx;
unsigned char buffer[4096];
unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
size_t len;
int len_out;
unsigned char *ek;
unsigned int eklen;
uint32_t eklen_n;
unsigned char iv[EVP_MAX_IV_LENGTH];
if (!PEM_read_RSAPrivateKey(rsa_pkey_file, &rsa_pkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Private Key File.\n");
ERR_print_errors_fp(stderr);
retval = 2;
goto out;
}
if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey))
{
fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
retval = 3;
goto out;
}
EVP_CIPHER_CTX_init(&ctx);
ek = malloc(EVP_PKEY_size(pkey));
/* First need to fetch the encrypted key length, encrypted key and IV */
if (fread(&eklen_n, sizeof eklen_n, 1, in_file) != 1)
{
perror("input file");
retval = 4;
goto out_free;
}
eklen = ntohl(eklen_n);
if (eklen > EVP_PKEY_size(pkey))
{
fprintf(stderr, "Bad encrypted key length (%u > %d)\n", eklen,
EVP_PKEY_size(pkey));
retval = 4;
goto out_free;
}
if (fread(ek, eklen, 1, in_file) != 1)
{
perror("input file");
retval = 4;
goto out_free;
}
if (fread(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, in_file) != 1)
{
perror("input file");
retval = 4;
goto out_free;
}
if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv, pkey))
{
fprintf(stderr, "EVP_OpenInit: failed.\n");
retval = 3;
goto out_free;
}
while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0)
{
if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer, len))
{
fprintf(stderr, "EVP_OpenUpdate: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
}
if (ferror(in_file))
{
perror("input file");
retval = 4;
goto out_free;
}
if (!EVP_OpenFinal(&ctx, buffer_out, &len_out))
{
fprintf(stderr, "EVP_SealFinal: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
out_free:
EVP_PKEY_free(pkey);
free(ek);
out:
return retval;
}
int main(int argc, char *argv[])
{
FILE *rsa_pkey_file;
int rv;
if (argc < 2)
{
fprintf(stderr, "Usage: %s <PEM RSA Private Key File>\n", argv[0]);
exit(1);
}
rsa_pkey_file = fopen(argv[1], "rb");
if (!rsa_pkey_file)
{
perror(argv[1]);
fprintf(stderr, "Error loading PEM RSA Private Key File.\n");
exit(2);
}
rv = do_evp_unseal(rsa_pkey_file, stdin, stdout);
fclose(rsa_pkey_file);
return rv;
}
Myślę, że to dość łatwe do naśladowania.
Nie mogę zrozumieć, dlaczego wprowadzasz algorytm symetrycznych algorytmów kryptograficznych do asymetrycznego systemu kryptograficznego klucza publicznego RSA? Czy to jest nawet poprawne? – scarface
@scarface: Z różnych powodów, asymetryczne systemy kluczy nie są używane do szyfrowania danych masowych - są używane do szyfrowania klucza dla systemu klucza symetrycznego, który sam jest używany do szyfrowania danych masowych. Dokładnie tak działa funkcja szyfrowania koperty EVP *. – caf
Idealnie, dziękuję bardzo. – scarface
- 1. Wynik klucza publicznego RSA RSA niepoprawny
- 2. szyfrowania RSA algorytm
- 3. szyfrowania RSA w Androidzie
- 4. Generowanie kluczy algorytmów RSA
- 5. Sprawdzanie podpisu RSA iOS
- 6. Szyfrowanie Java RSA - Decrypt .NET
- 7. Szyfrowanie RSA, uzyskiwanie bad długość
- 8. Szyfrowanie-Szyfrowanie RSA w iPhone
- 9. Szyfrowanie RSA .NET Szyfrowanie Java
- 10. Implementacje RSA w Objective C
- 11. Zintegruj RSA SecurID z aplikacją internetową bez uruchamiania Menedżera uwierzytelniania RSA
- 12. Jak załadować w Pythonie RSA publiczny klucz RSA z pliku wygenerowanego przy pomocy openssl?
- 13. OCR i breloczek RSA (token bezpieczeństwa)
- 14. jaki rozmiar bloku RSA max do kodowania?
- 15. obciążenia RSA klucz publiczny z pliku
- 16. szyfrowania RSA w Javie, odszyfrować w PHP
- 17. szyfrowania RSA w Objective-C (Mac)
- 18. Weryfikacja podpisu RSA OpenSSL: skrót i dopełnienie?
- 19. Openssl dla RSA: niezdefiniowane odniesienie do RSA_new
- 20. C# Szyfrowanie/deszyfrowanie RSA z transmisją
- 21. Jak skopiować EVP_PKEY, który zawiera klucz RSA?
- 22. Szyfrowanie klucza AES z kluczem publicznym RSA
- 23. PyCrypto: Generowanie klucza RSA chronionego hasłem DES3
- 24. pyinstaller: AttributeError: 'moduł' obiekt ma atrybut 'RSA'
- 25. SELinux zapobiega ssh z kluczem RSA
- 26. usunięcie hasła z RSA klucza prywatnego
- 27. Mała biblioteka RSA lub DSA bez zależności
- 28. Używanie języka RSA w języku C#
- 29. Jak uzyskać rozmiar klucza RSA w Javie
- 30. Implementacja pełnego pakietu RSA w języku Python
Powinieneś zacząć od rozrusznika podczas szyfrowania. Zazwyczaj szyfrujesz za pomocą klucza publicznego i odszyfrujesz klucz prywatny. –