Heim > Backend-Entwicklung > PHP-Tutorial > Das Problem des OpenSSL-RSA-Schlüsselformats löst das von PHP und C gemeinsam entwickelte Problem des Schlüsselformats

Das Problem des OpenSSL-RSA-Schlüsselformats löst das von PHP und C gemeinsam entwickelte Problem des Schlüsselformats

WBOY
Freigeben: 2016-08-08 09:24:22
Original
2995 Leute haben es durchsucht

OpenSSL-Programmierung – RSA-Programmierung im Detail
Dieser Artikel wurde am 26. Juni 2014 von Da Tong veröffentlicht, angesehen: 1.954 Mal, Kommentare: 0

1. RSA PEM-Dateiformat

1. PEM-Privatschlüsselformatdatei
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

2 . PEM-Datei im öffentlichen Schlüsselformat
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----

3. PEM RSAPublicKey-Format für den öffentlichen Schlüssel Datei
-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----

2. OpenSSL-Tastenbezogene Befehle

1. Schlüssel generieren
openssl genrsa -out key.pem 1024
-out gibt die generierte Datei an. Diese Datei enthält den öffentlichen Schlüssel und den privaten Schlüssel, sodass sie verschlüsselt oder entschlüsselt werden kann
1024 Die Länge des generierten Schlüssels

2. Extrahieren Sie den öffentlichen Schlüssel im PEM-Format
openssl rsa -in key.pem -pubout -out pubkey.pem
-in Geben Sie die Eingabeschlüsseldatei an
-out gibt die Datei zum Extrahieren des generierten öffentlichen Schlüssels an (PEM Public Key-Format)

3. Extrahieren Sie den öffentlichen Schlüssel im PEM RSAPublicKey-Format
openssl rsa -in key.pem -RSAPublicKey_out -out pubkey.pem
-in gibt die Eingabeschlüsseldatei an
-out gibt die Datei zum Extrahieren und Generieren des öffentlichen Schlüssels an (PEM RSAPublicKey-Format)

4. Openssl rsautl -encrypt -in input.file -inkey pubkey.pem -pubin -out output.file
-in gibt die verschlüsselte Datei an
-inkey gibt die verschlüsselte öffentliche Schlüsseldatei an
-pubin scheint mit einer reinen öffentlichen Schlüsseldatei verschlüsselt zu sein
-out Geben Sie die verschlüsselte Datei an

5. Entschlüsselungsdatei mit privatem Schlüssel
openssl rsautl -decrypt -in input.file -inkey key.pem -out output.file
-in Geben Sie an Zu entschlüsselnde Datei
-inkey gibt die private Schlüsseldatei an
-out gibt die entschlüsselte Datei an

3. RSA-bezogene API

1. Grundlegende Datenstruktur
struct {
BIGNUM * n ; 🎜> BIGNUM *q; // geheimer Primfaktor
BIGNUM *dmp1; // d mod (p-1)
BIGNUM *dmq1; >} RSA;


2. BN-Funktion für große Zahlenreihen
//Generieren Sie eine neue BIGNUM-Struktur
BIGNUM *BN_new(void);

//Release a BIGNUM-Struktur, nach der Veröffentlichung a=NULL;
void BN_free(BIGNUM *a);

//Alle Elemente auf 0 initialisieren, normalerweise BN_ init( &c)
void BN_init(BIGNUM *);

//Alle Elemente in a auf 0 zuweisen, aber der Speicher wird nicht freigegeben

void BN_clear(BIGNUM *a);


//Es entspricht der Kombination von BN_free und BN_clear, entweder den Wert 0 zuweisen oder Speicherplatz freigeben.

void BN_clear_free(BIGNUM *a);


//Setze die große Zahl a auf eine Ganzzahl w

int BN_set_word(BIGNUM *a, unsigned long w);


/ /Wenn die große Zahl a als langer Typ ausgedrückt werden kann, wird eine lange Typzahl zurückgegeben

unsigned long BN_get_word(BIGNUM *a);


//Erzeuge eine Pseudozufallszahl mit starken Bits für Verschlüsselung

/ /Wenn top=-1, das höchste Bit ist 0, top=0, das höchste Bit ist 1, top=1, das höchste und zweithöchste Bit sind 1, unten ist wahr, die Zufallszahl ist gerade

int BN_rand(BIGNUM *rnd , int bits, int top, int bottom);

//Konvertieren Sie a in einen String und speichern Sie ihn in to )

int BN_bn2bin(const BIGNUM *a, unsigned char *to);

//Wandle die längenstellige positive Ganzzahl in s in eine große Zahl um

BIGNUM *BN_bin2bn(const unsigned char * s, int len, BIGNUM *ret);

//Konvertieren Sie große Zahlen in hexadezimale Zeichenfolgen

char *BN_bn2hex(const BIGNUM *a);


//Konvertieren Sie große Zahlen in Dezimalzahlen strings

char *BN_bn2dec(const BIGNUM *a);


//Hexadezimale Zeichenfolge in große Zahl umwandeln

int BN_hex2bn(BIGNUM **a, const char *str);


//Übertragen Sie die Dezimalzeichenfolge in eine große Zahl
int BN_dec2bn(BIGNUM **a, const char *str);

3. RSA-Serienfunktionen

//Initialisieren Sie eine RSA-Struktur

RSA * RSA_new(void);

//Eine RSA-Struktur freigeben

void RSA_free(RSA *rsa);

//RSA-Privatschlüsselgenerierungsfunktion
// Generieren ein Schlüsselpaar Modulo Anzahl Bits, e ist der öffentliche Verschlüsselungsindex, im Allgemeinen 65537 (0x10001)
RSA *RSA_generate_key(int num, unsigned long e,void (*callback)(int,int,void * ), void *cb_arg );

//Beurteilen Sie die Anzahl der Ziffern, geben Sie die Anzahl der Ziffern im RSA-Modul zurück
int RSA_size(const RSA *rsa);

//Testen Sie, ob p und q Primzahlen sind
int RSA_check_key(RSA *rsa);

4. Funktionen der PEM-Serie
//Laden Sie das öffentliche Schlüsselzertifikat im RSAPublicKey-Format aus der Datei
RSA *PEM_read_RSAPublicKey(FILE *fp, RSA ** x, pem_password_cb *cb, void *u);

//Laden Sie das öffentliche Schlüsselzertifikat im RSAPublicKey-Format von BIO neu
RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x, pem_password_cb *cb, void * u);

//Das öffentliche Schlüsselzertifikat RSAPublicKey in die Datei ausgeben
int PEM_write_RSAPublicKey(FILE *fp, RSA *x);

//Das öffentliche Schlüsselzertifikat RSAPublicKey ausgeben an the BIO
int PEM_write_bio_RSAPublicKey(BIO *bp , RSA *x);

5. RSA-Verschlüsselungs-API
int RSA_public_encrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa , int padding);

Parameterbeschreibung:
flen: Länge der zu verschlüsselnden Informationen
von: zu verschlüsselnde Informationen
bis: verschlüsselte Informationen
padding: übernommenes Verschlüsselungsschema, unterteilt in: RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_SSLV23_PADDING, RSA_NO_PADDING

6. RSA-Entschlüsselungs-API
int RSA_private_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);

Parameterbeschreibung:
flen : Länge der zu entschlüsselnden Informationen
von: zu entschlüsselnde Informationen
bis: entschlüsselte Informationen
padding: übernommenes Entschlüsselungsschema

4. RSA-Programmierbeispiel

1. Beispiele für Datenverschlüsselung, Verschlüsselung und Entschlüsselung
#include
#include
#include
#include
#include
#include

#define PRIKEY "prikey.pem"
#define PUBKEY "pubkey.pem"
#define BUFFSIZE 4096

/**************************************************** * ************************
* RSA-Verschlüsselungs- und Entschlüsselungsfunktion
*
* Datei: test_rsa_encdec.c
* gcc -Wall -O2 -o test_rsa_encdec test_rsa_encdec.c -lcrypto -lssl
*
* Autor: tonglulin@gmail.com von www.qmailer.net
********************************************* ******************************/

char *my_encrypt(char *str, char *pubkey_path)
{
RSA *rsa = NULL ;
FILE *fp = NULL;
char *en = NULL;
int len ​​​​= 0;
int rsa_len = 0;

if ((fp = fopen(pubkey_path, "r")) == NULL) {
              return PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) == NULL) {
return NULL;

}


RSA_print_fp(stdout, rsa, 0);

len = strlen (str);

rsa_len = RSA_size(rsa);

en = (char *)malloc(rsa_len + 1);

memset(en, 0, rsa_len + 1);

if (RSA_public_encrypt(rsa_len, (unsigned char *)str, (unsigned char*)en , rsa, RSA_NO_PADDING) < 0) {

return NULL;
}

RSA_free( rsa);
fclose(fp);

return en;

}

char *my_decrypt(char *str, char *prikey_path)

{
RSA *rsa = NULL;

FILE *fp = NULL;

char *de = NULL ;
int rsa_len = 0;

if ((fp = fopen(prikey_path, "r") ) == NULL) {
          return NULL; 🎜> }

RSA_print_fp (stdout, rsa, 0);


rsa_len = RSA_size(rsa);
de = (char *)malloc(rsa_len + 1);

memset(de, 0, rsa_len + 1) ;


if (RSA_private_decrypt(rsa_len, (unsigned char *)str, (unsigned char*)de, rsa, RSA_NO_PADDING) < 0) {
return NULL;

}

RSA_free(rsa);

fclose(fp);

return de;

}


int main(int argc, char *argv[])
{

char *src = "hello, world!";

char *en = NULL;
char *de = NULL;

printf( "src is: %sn", src) ;

    en = my_encrypt(src, PUBKEY);
    printf("enc is: %sn", en);

    de= my_decrypt(en, PRIKEY);
    printf("dec ist: %sn", de);

    if (en != NULL) {
        free(en);
    }

    if (de != NULL) {
        free(de);
    }

    return 0;
}
 
2. PEM/BIGNUM公钥转换示例
 #include
#include

#include
#include

/**************************************************** * ************************
* RSA PEM/BIGNUM-Public-Key-Konvertierungsfunktion
*
* Datei: test_rsa_pubkey.c
* gcc -Wall -O2 -o test_rsa_pubkey test_rsa_pubkey.c -lcrypto -lssl
*
* Autor: tonglulin@gmail.com von www.qmailer.net
********************************************* ******************************/

const char *n = "C7301B330C4E123E4FA9F54F49121E8CE07974D8BFEF1D39EC9245D573D66E7FAC258F 86E2B0816C6BA875F10673E655E6A8DF48DEFDDB655E253ED5A4A0FBAD50D68E91D0459F9F2377BB8CA1583E3F83C06343A5A1177C903F498A6D14015CC975522BE 4446CD1EB87E88EF05A863AF0DD7C4D413CF603EDF4893EEC063BE3";

const char *pubkey = "- ----BEGIN RSA PUBLIC KEY-----nMIGJAoGBAMcwGzMMThI+T6n1T0kSHozgeXTYv+8dOeySRdVz1m5/rCWPhuKwgWxrnqHXxBnPmVeao30je/dtlXiU+1aSg+61Q1o6R0EWfnyN3u4yhWD4/g8BjQ 6WhF3yQnP0mKbRQBXMl1UivkRGzR64fojvBahjrw3XxNQTz2A+30iT7sBjvjAgMBAAE=n-----ENDE RSA PUBLIC KEY-----";

int main(int argc, char *argv[])
{
    RSA    *rsa = NULL;
    BIO    *bio = NULL;
    BIGNUM *bne = NULL;
    BIGNUM *bnn = NULL;
    FILE *fp = NULL;
    unsigned long e = 65537;

    if (argc < 2) {
        printf("%s pem|bignum argsn", argv[0]);
        return -1;
    }

    /* 将PEM转换为大数字符串 */
    if (strcasecmp(argv[1], "bignum") == 0) {
        if (argc == 3) {
            /* 从外部文件读 */
            fp =. fopen(ar gv [2], "r");
            if (fp == NULL) {
                return -1;
            }

            rsa = PEM_read_RSAPublicKey(fp, &rsa, N ULL, NULL);
            if (rsa == NULL) {
                return -1;
            }
        else {
            /* 从内存数据读 */
            bio = BIO_new(BIO_s_mem ());
            BIO_puts(bio, pubkey);

                  return -1 ;

            }
        }

        RSA_print_fp(stdout, rsa, 0);
        printf("%sn", BN_bn2hex(rsa->n));

       printf(" %sn", BN_bn2hex(rsa->e));

if (argc == 3) {
fclose(fp);
}
else {
BIO_free(bio);
}
RSA_free(rsa);
}
/* Große Zahlenzeichenfolge in PEM-Datei konvertieren*/
else if (strcasecmp(argv[1], "pem") == 0) {

bne = BN_new( );
if (bne == NULL) {
return -1;
}

bnn = BN_new();
if (bnn == NULL) {
BN_free( bne);
                                                                                                          ;
. BN_free(bne);

                                                                                                      * Settings Modulus*/

BN_set_word(bne, e);
if (argc == 3) {
BN_hex2bn(&bnn , argv[2]);
}
else {
BN_hex2bn(&bnn, n);

}


PEM_write_RSAPublicKey(stdout, rsa);

RSA_free (rsa);
}
else {
return -1 ;
}

return 0;
}

3. Beispiel für die Schlüsselgenerierung

#include

#include
#include
#include
#include < ;openssl/rsa.h>
#include

/**************************************************** * ********************
* RSA-Schlüsselgenerierungsfunktion
*
* Datei: test_rsa_genkey.c
* gcc -Wall - O2 -o test_rsa_genkey test_rsa_genkey.c -lcrypto
*
* Autor: tonglulin@gmail.com von www.qmailer.net
********************************************* ******************************/
int main(int argc, char *argv[])
{

/* RSA-Schlüssel generieren*/

RSA *rsa = RSA_generate_key(1024, 65537, NULL, NULL);

printf("BIGNUM: %sn", BN_bn2hex(rsa- >n));

/* Privaten Schlüssel extrahieren */
printf("PRIKEY:n");
PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, NULL, NULL) ;

/* Den öffentlichen Schlüssel extrahieren*/
unsigned char *n_b = (unsigned char *)calloc(RSA_size(rsa), sizeof(unsigned char));
unsigned char *e_b = (unsigned char *)calloc(RSA_size(rsa), sizeof(unsigned char)) ;

int n_size = BN_bn2bin(rsa->n, n_b);

int b_size = BN_bn2bin(rsa-> ;e, e_b);

RSA *pubrsa = RSA_new( );
pubrsa->n = BN_bin2bn(n_b, n_size, NULL);
pubrsa->e = BN_bin2bn(e_b , b_size, NULL);

printf("PUBKEY: n ");
PEM_write_RSAPublicKey(stdout, pubrsa);

RSA_free(rsa);

RSA_free(pubrsa);

return 0;

}

Das Obige stellt das Problem des OpenSSL-RSA-Schlüsselformats vor und löst das Schlüsselformatproblem der gemeinsamen Entwicklung von PHP und C, einschließlich Aspekten des Inhalts. Ich hoffe, es wird Freunden helfen, die sich für PHP-Tutorials interessieren.


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage