Openssl 1024bit RSA算法---公私钥获取和处理(一)

2023-11-08

1.简介

使用OpenSSL生成公私钥文件,然后再将文件中的信息读出的操作。

由于要对设备升级,需要用到RSA算法对一部分验证信息进行加密.

2.使用OpenSSL获取公私钥

我在window系统尝试安装OpenSSL,但是安装不上,我们可以使用linux自带的OpenSSL自动生成公私钥(我这里使用的Ubuntu)

打开终端,依次输入一下命令就可以生成我们想要的文件(生成文本文件,是为了便于查看文件内容;生成bin文件是为了接下来的文件操作)

//生成1024位的私钥
openssl genrsa -out private.pem 1024
 
//将生成的文件转换为文本
openssl rsa -in private.pem -text -out private.txt
 
//将BASE64编码的文件转换为bin文件
openssl   base64  -d  -in private.pem -out private.bin

详细关于私钥(PEM格式)参考:OPENSSL中RSA私钥文件(PEM格式)解析【一】 - 走看看

3.文件处理

3.1秘钥信息获取

通过查看生成的文本文件发现,不同的文件生成的文件长度不一样,有些会在头部自动添加一个“00”

为了解决不同文件的差异,消除“00”的影响,文件处理流程如下:

 上面的步骤还有uint32_t bits的位还没有设定,由于我们生成的1024bit的秘钥,所以我们将bits的值设为1024.如下所示的结构体,就是RSA私钥断开

//上面的流程主要是将生成的秘钥按格式填入
typedef struct
{
    uint32_t bits;                   /* length in bits of modulus */
    uint8_t  modulus[256];           /* modulus */
    uint8_t  publicExponent[4];      /* public exponent */
    uint8_t  exponent[256];          /* private exponent */
    uint8_t  prime[2][128];          /* prime factors */
    uint8_t  primeExponent[2][128];  /* exponents for CRT */
    uint8_t  coefficient[128];       /* CRT coefficient */ 
} R_RSA_PRIVATE_KEY;

3.2公钥信息获取 

typedef struct
{
    uint32_t bits;                   /* length in bits of modulus */
    uint8_t  modulus[256];           /* modulus */
    uint8_t  exponent[4];            /* public exponent */ 
} R_RSA_PUBLIC_KEY;

4.读取文件公私钥信息

#ifndef READ_PEM_FILE_H
#define READ_PEM_FILE_H
#include "file.h"
#include "s_rsa.h"
 
 
void generate_private_and_public_key(R_RSA_PRIVATE_KEY* privat_key, R_RSA_PUBLIC_KEY* public_key);
 
#endif
#include "read_pem_file.h"
 
 
 
static int is_private_pem_exist(void)//判断当前文件下有没有private.pem
{
    if(fopen("private.bin", "r"))
    {
        return 1;
    }
    else
    {
        printf("\n当前文件未找到private.bin这个文件,请用openssl工具生成\n\n");
        return 0;
    }
}
 
//从文件中读取私钥信息
static void read_private_pem(R_RSA_PRIVATE_KEY* privat_key)
{
    int i = 0;
    long long file_size = 0;
    char* flie_buffer;
    if(is_private_pem_exist() == 1)
    {
        flie_buffer = copyFile("private.bin", &file_size);
    }
    else
    {
        system("pause");
        exit(0);
    }
 
    //printf("%02x\n\n", file_size);
 
    //for(i = 1; i<= file_size; i++)
    //{
    //  printf("%02x ", (unsigned char)flie_buffer[i - 1]);
    //  if(i % 16 == 0)
    //  {
    //      printf("\n");
    //  }
    //}
 
 
 
    flie_buffer += 10;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 128; i++)
    {
        privat_key->modulus[i] = flie_buffer[i];
    }
    flie_buffer += 127;
 
    flie_buffer += 3;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 3; i++)
    {
        privat_key->publicExponent[i + 1] = flie_buffer[i];
    }
    flie_buffer += 2;
 
    flie_buffer += 4;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 128; i++)
    {
        privat_key->exponent[i] = flie_buffer[i];
    }
    flie_buffer += 127;
 
    flie_buffer += 3;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 64; i++)
    {
        privat_key->prime[0][i] = flie_buffer[i];
    }
    flie_buffer += 63;
 
    flie_buffer += 3;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 64; i++)
    {
        privat_key->prime[1][i] = flie_buffer[i];
    }
    flie_buffer += 63;
 
    flie_buffer += 3;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 64; i++)
    {
        privat_key->primeExponent[0][i] = flie_buffer[i];
    }
    flie_buffer += 63;
 
    flie_buffer += 3;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 64; i++)
    {
        privat_key->primeExponent[1][i] = flie_buffer[i];
    }
    flie_buffer += 63;
 
    flie_buffer += 3;
    if(*flie_buffer == 0)
    {
        flie_buffer += 1;
    }
    for(i = 0; i < 64; i++)
    {
        privat_key->coefficient[i] = flie_buffer[i];
    }
}
 
//打印私钥信息
static void prinf_privat_key(R_RSA_PRIVATE_KEY* privat_key)
{
    int i = 0;
    printf("\nmoduls:\n");
    for(i = 1; i <= 128; i++)
    {
        printf("%02x ",privat_key->modulus[i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
 
    printf("\npubicExpinent:\n");
    for(i = 0; i < 4; i++)
    {
        printf("%02x ",privat_key->publicExponent[i]);
    }
 
    printf("\nprivateExponent:\n");
    for(i = 1; i <= 128; i++)
    {
        printf("%02x ",privat_key->exponent[i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
 
    printf("\nprime1:\n");
    for(i = 1; i <= 64; i++)
    {
        printf("%02x ",privat_key->prime[0][i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
 
    printf("\nprime2:\n");
    for(i = 1; i <= 64; i++)
    {
        printf("%02x ",privat_key->prime[1][i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
 
    printf("\nexponent1:\n");
    for(i = 1; i <= 64; i++)
    {
        printf("%02x ",privat_key->primeExponent[0][i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
 
    printf("\nexponent2:\n");
    for(i = 1; i <= 64; i++)
    {
        printf("%02x ",privat_key->primeExponent[1][i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
 
    printf("\ncoefficient:\n");
    for(i = 1; i <= 64; i++)
    {
        printf("%02x ",privat_key->coefficient[i - 1]);
        if(i % 16 == 0)
        {
            printf("\n");
        }
    }
     
}
 
//填充bits以及给公钥赋值
//生成公钥,私钥
void generate_private_and_public_key(R_RSA_PRIVATE_KEY* privat_key, R_RSA_PUBLIC_KEY* public_key)
{
    public_key->bits = 1024;
    privat_key->bits = 1024;
 
    read_private_pem(privat_key);
    prinf_privat_key(privat_key);//读出私钥信息
 
    for(int i = 0; i < 4; i++)
    {
        public_key->exponent[i] = privat_key->publicExponent[i];
    }
    for(int i = 0; i < 256; i++)
    {
        public_key->modulus[i] = privat_key->modulus[i];
    }
}

 5. RSA标准算法

#ifndef S_RSA_H_
#define S_RSA_H_
 
typedef unsigned char uint8_t;
typedef unsigned int  uint32_t;
// ����ֵ����
#define RE_DATA 0x0401
#define RE_LEN  0x0406
 
/* RSA key lengths.
 */
#define MIN_RSA_MODULUS_BITS 508
/* #define MAX_RSA_MODULUS_BITS 1024 ** linq modify ->>2048 ***/
#define MAX_RSA_MODULUS_BITS 2048
#define MAX_RSA_MODULUS_LEN ((MAX_RSA_MODULUS_BITS + 7) / 8)
#define MAX_RSA_PRIME_BITS ((MAX_RSA_MODULUS_BITS + 1) / 2)
#define MAX_RSA_PRIME_LEN ((MAX_RSA_PRIME_BITS + 7) / 8)
 
/* Length of digit in bits */
#define NN_DIGIT_BITS 32
#define NN_HALF_DIGIT_BITS 16
/* Length of digit in bytes */
#define NN_DIGIT_LEN (NN_DIGIT_BITS / 8)
/* Maximum length in digits */
#define MAX_NN_DIGITS \
  ((MAX_RSA_MODULUS_LEN + NN_DIGIT_LEN - 1) / NN_DIGIT_LEN + 1)
/* Maximum digits */
#define MAX_NN_DIGIT 0xffffffff
#define MAX_NN_HALF_DIGIT 0xffff
 
/* Macros.
 */
#define LOW_HALF(x) ((x) & MAX_NN_HALF_DIGIT)
#define HIGH_HALF(x) (((x) >> NN_HALF_DIGIT_BITS) & MAX_NN_HALF_DIGIT)
#define TO_HIGH_HALF(x) (((NN_DIGIT)(x)) << NN_HALF_DIGIT_BITS)
#define DIGIT_MSB(x) (uint32_t)(((x) >> (NN_DIGIT_BITS - 1)) & 1)
#define DIGIT_2MSB(x) (uint32_t)(((x) >> (NN_DIGIT_BITS - 2)) & 3)
 
#define NN_ASSIGN_DIGIT(a, b, digits) {NN_AssignZero (a, digits); a[0] = b;}
#define NN_EQUAL(a, b, digits) (! NN_Cmp (a, b, digits))
#define NN_EVEN(a, digits) (((digits) == 0) || ! (a[0] & 1))
 
 
typedef struct     // ��Կ�ṹ
{
    uint32_t bits;                   /* length in bits of modulus */
    uint8_t  modulus[256];           /* modulus */
    uint8_t  exponent[4];            /* public exponent */ 
} R_RSA_PUBLIC_KEY;
 
typedef struct    // ˽Կ�ṹ
{
    uint32_t bits;                   /* length in bits of modulus */
    uint8_t  modulus[256];           /* modulus */
    uint8_t  publicExponent[4];      /* public exponent */
    uint8_t  exponent[256];          /* private exponent */
    uint8_t  prime[2][128];          /* prime factors */
    uint8_t  primeExponent[2][128];  /* exponents for CRT */
    uint8_t  coefficient[128];       /* CRT coefficient */ 
} R_RSA_PRIVATE_KEY;
 
 
int  rsa_public(void *outbuf, int *outlen, const void *inbuf, int inlen, const R_RSA_PUBLIC_KEY *pubkey);
int  rsa_private(void *outbuf, int *outlen, const void *inbuf, int inlen, const R_RSA_PRIVATE_KEY *prikey);
 
#endif
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "s_rsa.h"
 
typedef uint32_t NN_DIGIT;
typedef uint16_t NN_HALF_DIGIT;
 
/****************************************************************************
  ??????     :  void dmult(uint32_t a, uint32_t b, uint32_t *cHigh, uint32_t *cLow)
  ????       :  32λ???????????
****************************************************************************/
void dmult(uint32_t a, uint32_t b, uint32_t *cHigh, uint32_t *cLow)
{
    uint64_t temp1,temp2,temp3;
 
    temp1 = a;
    temp2 = b;
 
    temp3 = temp1*temp2;
 
    *cHigh = temp3>>32;
    *cLow = temp3;
}
 
/****************************************************************************
  ??????     :
  ????       :
  ???????   :
  ???????   :
  ?????     :
  ??????   :
      ?????     ??????    ???汾??   ??????
  1??
****************************************************************************/
NN_DIGIT subdigitmult(NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT c, NN_DIGIT *d, NN_DIGIT digits)
{
    NN_DIGIT borrow, thigh, tlow;
    NN_DIGIT i;
 
    borrow = 0;
 
    if(c != 0)
    {
        for(i = 0; i < digits; i++)
        {
            dmult(c, d[i], &thigh, &tlow);
            if((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
                borrow = 1;
            else
                borrow = 0;
            if((a[i] -= tlow) > (MAX_NN_DIGIT - tlow))
                borrow++;
            borrow += thigh;
        }
    }
    return (borrow);
}
 
/* Decodes character string b into a, where character string is ordered
   from most to least significant.
 
   Lengths: a[digits], b[len].
   Assumes b[i] = 0 for i < len - digits * NN_DIGIT_LEN. (Otherwise most
   significant bytes are truncated.)
 */
void NN_Decode (NN_DIGIT *a, uint32_t digits, uint8_t *b, uint32_t len)
{
    NN_DIGIT t;
    int32_t j;
    uint32_t i, u;
 
    for (i = 0, j = len - 1; i < digits && j >= 0; i++)
    {
        t = 0;
        for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
        {
            t |= ((NN_DIGIT)b[j]) << u;
        }
        a[i] = t;
    }
 
    for (; i < digits; i++)
        a[i] = 0;
}
 
/* Encodes b into character string a, where character string is ordered
   from most to least significant.
 
   Lengths: a[len], b[digits].
   Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant
   digits are truncated.)
 */
void NN_Encode (uint8_t *a, uint32_t len, NN_DIGIT *b, uint32_t digits)
{
    NN_DIGIT t;
    int32_t j;
    uint32_t i, u;
 
    for (i = 0, j = len - 1; i < digits && j >= 0; i++)
    {
        t = b[i];
        for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
            a[j] = (uint8_t)(t >> u);
    }
 
    for (; j >= 0; j--)
        a[j] = 0;
}
 
/* Assigns a = b.
 
   Lengths: a[digits], b[digits].
 */
void NN_Assign (NN_DIGIT *a, NN_DIGIT *b, uint32_t digits)
{
    if(digits)
    {
        do
        {
            *a++ = *b++;
        }while(--digits);
    }
}
 
/* Assigns a = 0.
 
   Lengths: a[digits].
 */
void NN_AssignZero (NN_DIGIT *a, uint32_t digits)
{
    if(digits)
    {
        do
        {
            *a++ = 0;
        }while(--digits);
    }
}
 
/* Returns the significant length of a in bits, where a is a digit.
 */
static uint32_t NN_DigitBits (NN_DIGIT a)
{
    uint32_t i;
 
    for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1)
    {
        if (a == 0)
            break;
    }
 
    return (i);
}
 
/* Returns the significant length of a in digits.
 
   Lengths: a[digits].
 */
uint32_t NN_Digits (NN_DIGIT *a, uint32_t digits)
{
    int32_t i;
 
    for (i = digits - 1; i >= 0; i--)
    {
        if (a[i])
            break;
    }
 
    return (i + 1);
}
 
/* Returns sign of a - b.
   Lengths: a[digits], b[digits].
 */
int32_t NN_Cmp (NN_DIGIT *a, NN_DIGIT *b, uint32_t digits)
{
    int32_t i;
 
    for (i = digits - 1; i >= 0; i--)
    {
        if (a[i] > b[i])
            return (1);
        if (a[i] < b[i])
            return (-1);
    }
 
    return (0);
}
 
/* Computes a = b + c. Returns carry.
 
   Lengths: a[digits], b[digits], c[digits].
 */
NN_DIGIT NN_Add (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, uint32_t digits)
{
    NN_DIGIT ai, carry;
    uint32_t i;
 
    carry = 0;
 
    for (i = 0; i < digits; i++)
    {
        if ((ai = b[i] + carry) < carry)
            ai = c[i];
        else if ((ai += c[i]) < c[i])
            carry = 1;
        else
            carry = 0;
        a[i] = ai;
    }
 
    return (carry);
}
 
 
/* Computes a = b - c. Returns borrow.
 
   Lengths: a[digits], b[digits], c[digits].
 */
NN_DIGIT NN_Sub (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, uint32_t digits)
{
    NN_DIGIT ai, borrow;
    uint32_t i;
 
    borrow = 0;
 
    for (i = 0; i < digits; i++)
    {
        if ((ai = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
            ai = MAX_NN_DIGIT - c[i];
        else if ((ai -= c[i]) > (MAX_NN_DIGIT - c[i]))
            borrow = 1;
        else
            borrow = 0;
        a[i] = ai;
    }
 
    return (borrow);
}
 
/* Computes a = b * 2^c (i.e., shifts left c bits), returning carry.
 
   Lengths: a[digits], b[digits].
   Requires c < NN_DIGIT_BITS.
 */
NN_DIGIT NN_LShift (NN_DIGIT *a, NN_DIGIT *b, uint32_t c, uint32_t digits)
{
    NN_DIGIT bi, carry;
    uint32_t i, t;
 
    if (c >= NN_DIGIT_BITS)
        return (0);
 
    t = NN_DIGIT_BITS - c;
 
    carry = 0;
 
    for (i = 0; i < digits; i++)
    {
        bi = b[i];
        a[i] = (bi << c) | carry;
        carry = c ? (bi >> t) : 0;
    }
 
    return (carry);
}
 
/* Computes a = c div 2^c (i.e., shifts right c bits), returning carry.
 
   Lengths: a[digits], b[digits].
   Requires: c < NN_DIGIT_BITS.
 */
NN_DIGIT NN_RShift (NN_DIGIT *a, NN_DIGIT *b, uint32_t c, uint32_t digits)
{
    NN_DIGIT bi, carry;
    int32_t i;
    uint32_t t;
 
    if (c >= NN_DIGIT_BITS)
        return (0);
 
    t = NN_DIGIT_BITS - c;
 
    carry = 0;
 
    for (i = digits - 1; i >= 0; i--)
    {
        bi = b[i];
        a[i] = (bi >> c) | carry;
        carry = c ? (bi << t) : 0;
    }
 
    return (carry);
}
 
 
/* Computes a = b * c.
 
   Lengths: a[2*digits], b[digits], c[digits].
   Assumes digits < MAX_NN_DIGITS.
 */
void NN_Mult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, uint32_t digits)
{
    NN_DIGIT dhigh, dlow, carry;
    NN_DIGIT bDigits, cDigits, i, j;
    NN_DIGIT mt[2*MAX_NN_DIGITS];
 
    NN_AssignZero (mt, 2 * digits);
 
    bDigits = NN_Digits (b, digits);
    cDigits = NN_Digits (c, digits);
 
    for (i = 0; i < bDigits; i++)
    {
        carry = 0;
        if(*(b+i) != 0)
        {
            for(j = 0; j < cDigits; j++)
            {              
                dmult(*(b+i), *(c+j), &dhigh, &dlow);              
                if((*(mt+(i+j)) = *(mt+(i+j)) + carry) < carry)
                    carry = 1;
                else
                    carry = 0;
                if((*(mt+(i+j)) += dlow) < dlow)
                    carry++;
                carry += dhigh;
            }
        }
        *(mt+(i+cDigits)) += carry;
    }
     
    NN_Assign (a, mt, 2 * digits); 
 
    /* Zeroize potentially sensitive information.
    */
    memset ((uint8_t *)mt, 0, sizeof (mt));
}
 
/* Computes a = c div d and b = c mod d.
 
   Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits].
   Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS,
           dDigits < MAX_NN_DIGITS.
 */
void NN_Div (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, uint32_t cDigits, NN_DIGIT *d, uint32_t dDigits)
{
    NN_DIGIT ai;
    int32_t i;
    uint32_t ddDigits, shift;
    NN_DIGIT div_cc[2*MAX_NN_DIGITS+1], div_dd[MAX_NN_DIGITS]; // ?????????м????
 
    NN_DIGIT s;
    NN_DIGIT t[2], u, v, *ccptr;
    NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;
 
    ddDigits = NN_Digits (d, dDigits);
    if (ddDigits == 0)
        return;
 
    /* Normalize operands.
    */
    shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]);
    NN_AssignZero (div_cc, ddDigits);
    div_cc[cDigits] = NN_LShift (div_cc, c, shift, cDigits);
    NN_LShift (div_dd, d, shift, ddDigits);
 
    s = div_dd[ddDigits-1];
 
    NN_AssignZero (a, cDigits);
 
    for (i = cDigits-ddDigits; i >= 0; i--)
    {
        if (s == MAX_NN_DIGIT)
        {
            ai = div_cc[i+ddDigits];
        }
        else
        {
            ccptr = &div_cc[i+ddDigits-1];
 
            s++;
            cHigh = (NN_HALF_DIGIT)HIGH_HALF(s);
            cLow = (NN_HALF_DIGIT)LOW_HALF(s);
 
            *t = *ccptr;
            *(t+1) = *(ccptr+1);
 
            if (cHigh == MAX_NN_HALF_DIGIT)
            {
                aHigh = (NN_HALF_DIGIT)HIGH_HALF(*(t+1));
            }
            else
            {
                aHigh = (NN_HALF_DIGIT)(*(t+1) / (cHigh + 1));
            }
            u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow;
            v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh;
            if ((*t -= TO_HIGH_HALF(u)) > (MAX_NN_DIGIT - TO_HIGH_HALF(u)))
            {
                t[1]--;
            }
            *(t+1) -= HIGH_HALF(u);
            *(t+1) -= v;
 
            while ((*(t+1) > cHigh) ||   ((*(t+1) == cHigh) && (*t >= TO_HIGH_HALF(cLow))))
            {
                if ((*t -= TO_HIGH_HALF(cLow)) > MAX_NN_DIGIT - TO_HIGH_HALF(cLow))
                    t[1]--;
                *(t+1) -= cHigh;
                aHigh++;
            }
 
            if (cHigh == MAX_NN_HALF_DIGIT)
            {
                aLow = (NN_HALF_DIGIT)LOW_HALF(*(t+1));
            }
            else
            {
                aLow = (NN_HALF_DIGIT)((TO_HIGH_HALF(*(t+1)) + HIGH_HALF(*t)) / (cHigh + 1));
            }
            u = (NN_DIGIT)aLow * (NN_DIGIT)cLow;
            v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh;
            if ((*t -= u) > (MAX_NN_DIGIT - u))
                t[1]--;
            if ((*t -= TO_HIGH_HALF(v)) > (MAX_NN_DIGIT - TO_HIGH_HALF(v)))
                t[1]--;
            *(t+1) -= HIGH_HALF(v);
 
            while ((*(t+1) > 0) || ((*(t+1) == 0) && *t >= s))
            {
                if ((*t -= s) > (MAX_NN_DIGIT - s))
                    t[1]--;
                aLow++;
            }
 
            ai = TO_HIGH_HALF(aHigh) + aLow;
            s--;
        }
 
        div_cc[i+ddDigits] -= subdigitmult(&div_cc[i], &div_cc[i], ai, div_dd, ddDigits);
 
        while (div_cc[i+ddDigits] || (NN_Cmp(&div_cc[i], div_dd, ddDigits) >= 0))
        {
            ai++;
            div_cc[i+ddDigits] -= NN_Sub(&div_cc[i], &div_cc[i], div_dd, ddDigits);
        }
 
        a[i] = ai;
    }
 
    /* Restore result.
    */
    NN_AssignZero (b, dDigits);
    NN_RShift (b, div_cc, shift, ddDigits);
 
    /* Zeroize potentially sensitive information.
    */
    memset ((uint8_t *)div_cc, 0, sizeof (div_cc));
    memset ((uint8_t *)div_dd, 0, sizeof (div_dd));
}
 
/* Computes a = b mod c.
 
   Lengths: a[cDigits], b[bDigits], c[cDigits].
   Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS.
 */
void NN_Mod (NN_DIGIT *a, NN_DIGIT *b, uint32_t bDigits, NN_DIGIT *c, uint32_t cDigits)
{
    NN_DIGIT mod_t[2 * MAX_NN_DIGITS];    // ??????м????
 
    NN_Div (mod_t, a, b, bDigits, c, cDigits);
 
    /* Zeroize potentially sensitive information.
    */
    memset ((uint8_t *)mod_t, 0, sizeof (mod_t));
}
 
/* Computes a = b * c mod d.
 
   Lengths: a[digits], b[digits], c[digits], d[digits].
   Assumes d > 0, digits < MAX_NN_DIGITS.
 */
void NN_ModMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, NN_DIGIT *d, uint32_t digits)
{
    NN_DIGIT mod_t[2 * MAX_NN_DIGITS];    // ??????м????
 
    NN_Mult (mod_t, b, c, digits);
    NN_Mod (a, mod_t, 2 * digits, d, digits);
 
    /* Zeroize potentially sensitive information.
    */
    memset ((uint8_t *)mod_t, 0, sizeof (mod_t));
}
 
/* Computes a = b^c mod d.
 
   Lengths: a[dDigits], b[dDigits], c[cDigits], d[dDigits].
   Assumes d > 0, cDigits > 0, dDigits < MAX_NN_DIGITS.
 */
void NN_ModExp (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, uint32_t cDigits, NN_DIGIT *d, uint32_t dDigits)
{
    int32_t i;
    uint32_t ciBits, j, s;
    NN_DIGIT ci;
    NN_DIGIT bPower[3][MAX_NN_DIGITS], Exp_t[MAX_NN_DIGITS];   // ????????м????
 
    /* Store b, b^2 mod d, and b^3 mod d.
    */
    NN_Assign (bPower[0], b, dDigits);
    NN_ModMult (bPower[1], bPower[0], b, d, dDigits);
    NN_ModMult (bPower[2], bPower[1], b, d, dDigits);
 
    NN_ASSIGN_DIGIT (Exp_t, 1, dDigits);
 
    cDigits = NN_Digits (c, cDigits);
    for (i = cDigits - 1; i >= 0; i--)
    {
        ci = c[i];
        ciBits = NN_DIGIT_BITS;
 
        /* Scan past leading zero bits of most significant digit.
        */
        if (i == (int)(cDigits - 1))
        {
            while (! DIGIT_2MSB (ci))
            {
                ci <<= 2;
                ciBits -= 2;
            }
        }
 
        for (j = 0; j < ciBits; j += 2, ci <<= 2)
        {
            /* Compute t = t^4 * b^s mod d, where s = two MSB's of ci.
            */
            NN_ModMult (Exp_t, Exp_t, Exp_t, d, dDigits);
            NN_ModMult (Exp_t, Exp_t, Exp_t, d, dDigits);
            if ((s = DIGIT_2MSB (ci)) != 0)
                NN_ModMult (Exp_t, Exp_t, bPower[s-1], d, dDigits);
        }
    }
 
    NN_Assign (a, Exp_t, dDigits);
 
    /* Zeroize potentially sensitive information.
    */
    memset ((uint8_t *)bPower, 0, sizeof (bPower));
    memset ((uint8_t *)Exp_t, 0, sizeof (Exp_t));
}
 
static int32_t RSAPublicBlock (uint8_t *output,                  /* output block */
                                uint32_t *outputLen,              /* length of output block */
                                uint8_t *input,                   /* input block */
                                uint32_t inputLen,                /* length of input block */
                                R_RSA_PUBLIC_KEY *publicKey)    /* RSA public key */
{
    uint32_t eDigits, nDigits;
    NN_DIGIT pc[MAX_NN_DIGITS];           // ???????????????
    NN_DIGIT pe[MAX_NN_DIGITS];           // ??????
    NN_DIGIT pm[MAX_NN_DIGITS];           // ????????
    NN_DIGIT pn[MAX_NN_DIGITS];           // ????
 
    // ??????:??????????????RSA???????????????
    // ???????????????????256????
    NN_Decode (pm, MAX_NN_DIGITS, input, inputLen);
    //NN_Decode (pn, MAX_NN_DIGITS, publicKey->modulus, MAX_RSA_MODULUS_LEN);
    NN_Decode (pn, MAX_NN_DIGITS, publicKey->modulus, publicKey->bits/8);
    NN_Decode (pe, MAX_NN_DIGITS, publicKey->exponent, 4);
    nDigits = NN_Digits (pn, MAX_NN_DIGITS);
    eDigits = NN_Digits (pe, MAX_NN_DIGITS);
 
    if (NN_Cmp (pm, pn, nDigits) >= 0)
        return (RE_DATA);
 
    /* Compute pc = pm^pe mod pn.
    */
    NN_ModExp (pc, pm, pe, eDigits, pn, nDigits);
 
    *outputLen = (publicKey->bits + 7) / 8;
    NN_Encode (output, *outputLen, pc, nDigits);
 
    /* Zeroize sensitive information.
    */
    memset ((uint8_t *)pc, 0, sizeof (pc));
    memset ((uint8_t *)pm, 0, sizeof (pm));
 
    return (0);
}
 
/* Raw RSA private-key operation. Output has same length as modulus.
 
   Assumes inputLen < length of modulus.
   Requires input < modulus.
 */
static int32_t RSAPrivateBlock (uint8_t *output,            /* output block */
                                 uint32_t *outputLen,           /* length of output block */
                                 uint8_t *input,              /* input block */
                                 uint32_t inputLen,             /* length of input block */
                                 R_RSA_PRIVATE_KEY *privateKey)     /* RSA private key */
{
    uint32_t cDigits, nDigits, pDigits, OutLen;
    NN_DIGIT c[MAX_NN_DIGITS];            // ?????????????????????
    NN_DIGIT cP[MAX_NN_DIGITS];           // c?p???????
    NN_DIGIT cQ[MAX_NN_DIGITS];           // c?q???????
    NN_DIGIT dP[MAX_NN_DIGITS];           // ?????p????
    NN_DIGIT dQ[MAX_NN_DIGITS];           // ?????q????
    NN_DIGIT mP[MAX_NN_DIGITS];           // mP = cP^dP mod p
    NN_DIGIT mQ[MAX_NN_DIGITS];           // mQ = cQ^dQ mod q
    NN_DIGIT n[MAX_NN_DIGITS];            // ???
    NN_DIGIT p[MAX_NN_DIGITS];            // ??p????
    NN_DIGIT q[MAX_NN_DIGITS];            // ??q????
    NN_DIGIT qInv[MAX_NN_DIGITS];         // ??p??q????????
    NN_DIGIT t[MAX_NN_DIGITS];            // ??????????????
 
    NN_Decode (c, MAX_NN_DIGITS, input, inputLen);
 
    // ??????:??????????????RSA???????????????
    // ???????????????????256????
    /*NN_Decode(n, MAX_NN_DIGITS, privateKey->modulus, MAX_RSA_MODULUS_LEN);
    NN_Decode(p, MAX_NN_DIGITS, privateKey->prime[0], MAX_RSA_PRIME_LEN);
    NN_Decode(q, MAX_NN_DIGITS, privateKey->prime[1], MAX_RSA_PRIME_LEN);
    NN_Decode(dP, MAX_NN_DIGITS, privateKey->primeExponent[0], MAX_RSA_PRIME_LEN);
    NN_Decode(dQ, MAX_NN_DIGITS, privateKey->primeExponent[1], MAX_RSA_PRIME_LEN);
    NN_Decode(qInv, MAX_NN_DIGITS, privateKey->coefficient, MAX_RSA_PRIME_LEN);*/
 
    NN_Decode(n, MAX_NN_DIGITS, privateKey->modulus, privateKey->bits/8);
    NN_Decode(p, MAX_NN_DIGITS, privateKey->prime[0], privateKey->bits/16);
    NN_Decode(q, MAX_NN_DIGITS, privateKey->prime[1], privateKey->bits/16);
    NN_Decode(dP, MAX_NN_DIGITS, privateKey->primeExponent[0], privateKey->bits/16);
    NN_Decode(dQ, MAX_NN_DIGITS, privateKey->primeExponent[1], privateKey->bits/16);
    NN_Decode(qInv, MAX_NN_DIGITS, privateKey->coefficient, privateKey->bits/16);
 
    cDigits = NN_Digits (c, MAX_NN_DIGITS);
    nDigits = NN_Digits (n, MAX_NN_DIGITS);
    pDigits = NN_Digits (p, MAX_NN_DIGITS);
 
    if (NN_Cmp (c, n, nDigits) >= 0)
        return (RE_DATA);
 
    /* Compute mP = cP^dP mod p  and  mQ = cQ^dQ mod q. (Assumes q has
    length at most pDigits, i.e., p > q.)
    */
    NN_Mod (cP, c, cDigits, p, pDigits);
    NN_Mod (cQ, c, cDigits, q, pDigits);
    NN_ModExp (mP, cP, dP, pDigits, p, pDigits);
    NN_AssignZero (mQ, nDigits);
    NN_ModExp (mQ, cQ, dQ, pDigits, q, pDigits);
 
    /* Chinese Remainder Theorem:
    m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ.
    */
    if (NN_Cmp (mP, mQ, pDigits) >= 0)
        NN_Sub (t, mP, mQ, pDigits);
    else
    {
        NN_Sub (t, mQ, mP, pDigits);
        NN_Sub (t, p, t, pDigits);
    }
    NN_ModMult (t, t, qInv, p, pDigits);
    NN_Mult (t, t, q, pDigits);
    NN_Add (t, t, mQ, nDigits);
 
    OutLen = (privateKey->bits + 7) / 8;
    if(outputLen != NULL)
    {
        *outputLen = OutLen;
    }
    if(output != NULL)
    {
        NN_Encode (output, OutLen, t, nDigits);
    }
 
    /* Zeroize sensitive information.
    */
    memset ((uint8_t *)c, 0, sizeof (c));
    memset ((uint8_t *)cP, 0, sizeof (cP));
    memset ((uint8_t *)cQ, 0, sizeof (cQ));
    memset ((uint8_t *)dP, 0, sizeof (dP));
    memset ((uint8_t *)dQ, 0, sizeof (dQ));
    memset ((uint8_t *)mP, 0, sizeof (mP));
    memset ((uint8_t *)mQ, 0, sizeof (mQ));
    memset ((uint8_t *)p, 0, sizeof (p));
    memset ((uint8_t *)q, 0, sizeof (q));
    memset ((uint8_t *)qInv, 0, sizeof (qInv));
    memset ((uint8_t *)t, 0, sizeof (t));
 
    return (0);
}
 
 
int  rsa_public(void *outbuf, int *outlen, const void *inbuf, int inlen, const R_RSA_PUBLIC_KEY *pubkey)
{
    int status;
    uint32_t modulusLen, pkcsBlockLen=0;
    uint8_t pkcsBlock[MAX_RSA_MODULUS_LEN]; // ????????????????????????
 
    if((outbuf == NULL) || (pubkey == NULL)) {
        return(-1);
    }
    modulusLen = (pubkey->bits + 7) / 8;
    if (inlen > modulusLen){
        return (RE_LEN);
    }
 
    status = RSAPublicBlock(pkcsBlock, &pkcsBlockLen, (uint8_t *)inbuf, inlen, (R_RSA_PUBLIC_KEY *)pubkey);
    if(status){
        return (status);
    }
 
    if(pkcsBlockLen != modulusLen){
        return (RE_LEN);
    }
     
    if(outlen != NULL){
        *outlen = modulusLen;
    }
 
    if(outbuf != NULL){
        memcpy(outbuf, pkcsBlock, modulusLen);
    }
 
    /* Zeroize potentially sensitive information.
    */
    memset(pkcsBlock, 0, sizeof (pkcsBlock));
 
    return (0);
}
 
 
int  rsa_private(void *outbuf, int *outlen, const void *inbuf, int inlen, const R_RSA_PRIVATE_KEY *prikey)
{
    int status;
    uint32_t i, modulusLen;
    uint8_t pkcsBlock[MAX_RSA_MODULUS_LEN]; // ??????????????????????
 
    if((inbuf == NULL) || (prikey == NULL)){
        return(-1);
    }
    modulusLen = (prikey->bits + 7) / 8;
 
    if (inlen  > modulusLen){
        return (RE_LEN);
    }
 
    i = 0;
    memcpy (pkcsBlock+i, inbuf, inlen);
 
    *outlen = 0;
    status = RSAPrivateBlock((uint8_t*)outbuf, (uint32_t *)outlen, pkcsBlock, modulusLen, (R_RSA_PRIVATE_KEY *)prikey);
 
    /* Zeroize potentially sensitive information.
    */
    memset (pkcsBlock, 0, sizeof (pkcsBlock));
 
    return (status);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Openssl 1024bit RSA算法---公私钥获取和处理(一) 的相关文章

  • 即使 makefile 和源代码存在,为什么“Build Project”在 Eclipse Helios CDT 中显示为灰色?

    我无法构建我的项目 我在 Eclipse Helios 中创建了一个新的 CDT 项目 并告诉它使用现有的源代码和 makefile 这两者都正确显示在 Package 和 Project 视图中 然而 项目 菜单中的 构建全部 和 构建项
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • Mono 和 WebRequest 速度 - 测试

    在 mono 4 6 2 linux 中 我注意到 wget 下载文件的速度与webclient DownloadString 所以我做了一个小测试来调查 为什么 wget 明显比 C 快 根据我自己的实验 使用 wget 下载 手动读取文
  • 跟踪 pthread 调度

    我想做的是创建某种图表 详细说明 Linux 中 两个 线程的执行情况 我不需要查看线程的作用 只需查看它们何时被安排以及持续多长时间 基本上是一条时间线 在过去的几个小时里 我一直在互联网上搜索跟踪 pthread 调度的方法 不幸的是
  • Alsa 带有来自调制解调器的 PCM 接口

    我有一个基于 imx28 CPU 的定制板 CPU 的串行端口连接到调制解调器的 PCM 输出 我必须为调制解调器的 PCM 接口开发一个驱动程序 使其成为 ALSA SoC 的一部分 您能指出内核树 中与我的设置重新组合的一些驱动程序吗
  • 无法安装 psycopg2 Ubuntu

    试图为 django 项目准备好服务器 但我在设置 postgres 时遇到了一些问题 我正在遵循本指南 https jee appy blogspot com 2017 01 deply django with nginx html ht
  • /proc/PID 文件格式

    我想从中检索一些流程信息 proc目录 我的问题如下 中的文件是否有标准格式 proc PID 例如 有这个proc PID status文件与Name t ProcName在第一行 我可以在其他地方用空格代替这个文件吗 t或者类似的东西
  • 如何从最新版本的 Ubuntu (18.10) 运行使用 SystemD 的 Docker 容器?

    我正在尝试执行使用 ubuntu latest 构建的 Docker 映像 并且在运行容器时不断收到 SystemD 错误消息 System has not been booted with systemd as init system P
  • 是否有可能通过 mmap 匿名内存“打孔”?

    考虑一个使用大量大致页面大小的内存区域 例如 64 kB 左右 的程序 每个内存区域的寿命都相当短暂 在我的特定情况下 这些是绿色线程的替代堆栈 如何最好地分配这些区域 以便一旦该区域不再使用 它 们的页面可以返回到内核 天真的解决方案显然
  • 编写多个mysql脚本

    是否可以在复合脚本中包含其他 mysql 脚本 理想情况下 我不想为包含的脚本创建存储过程 对于较大的项目 我想分层维护几个较小的脚本 然后根据需要组合它们 但现在 我很乐意学习如何包含其他脚本 source是一个内置命令 您可以在 MyS
  • Linux 文本文件操作

    我有一个格式的文件 a href a href a href a href 我需要选择 之后但 之前的文本 并将其打印在行尾 添加后 例如 a href http www wowhead com search Su a a a a a
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • 在 Ubuntu 16.04 中创建虚拟主机

    我已经开始在 laravel 中工作并使用 lampp 我看过很多使用虚拟主机来制作用户友好的 url 的教程 我想在 Ubuntu 16 04 上执行此操作 以下教程对我不起作用 https ourcodeworld com articl
  • sqlite 插入需要很长时间

    我正在将不到 200 000 行插入到 sqlite 数据库表中 我只是在终端中通过 sqlite3 使用一个非常简单的 sql 文件 我打赌它已经运行了至少 30 分钟 这是正常现象还是我应该关闭该过程并尝试不同的方法 sqlite中的插
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • linux下如何获取昨天和前天?

    我想在变量中获取 sysdate 1 和 sysdate 2 并回显它 我正在使用下面的查询 它将今天的日期作为输出 bin bash tm date Y d m echo tm 如何获取昨天和前天的日期 这是另一种方法 对于昨天来说 da
  • Gradle 1.3:build.gradle 不构建类

    这里有一个新问题 我有一个 build gradle 文件apply plugin java在其中 并与 java 项目 包关联 当我跑步时gradle build从命令行我得到 compileJava UP TO DATE process
  • Linux 中的电源管理通知

    在基于 Linux 的系统中 我们可以使用哪些方法 最简单的方法 来获取电源状态更改的通知 例如 当计算机进入睡眠 休眠状态等时 我需要这个主要是为了在睡眠前保留某些状态 当然 在计算机唤醒后恢复该状态 您只需配置即可获得所有这些事件acp
  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进

随机推荐

  • HTTP 和 HTTPS详解

    HTTP 和 HTTPS详解 目录 HTTP 和 HTTPS详解 1 http 和 https 概述 1 1 什么是http 1 2 什么是https 1 3 两者之间的区别 2 工作原理 2 1 Http工作原理 2 2 Https工作原
  • IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/

    idea下载官网一键直达 点击跳转
  • c++子类访问父类保护成员,只能通过子类对象

    1 前言 我们知道 对外部来讲 一个类的private和protected成员 外部都不能直接访问 那么 对子类来说呢 子类如果以public方式继承父类 它还是不能直接访问private成员 并且虽然它可以访问protected成员 也是
  • [Spring学习]06 Spring Bean的生命周期

    目录 一 Spring bean的生命周期 二 连接池配置 三 延时加载机制 一 Spring bean的生命周期 传统的Java应用中 bean的生命周期为 使用new 进行Bean的实例化 然后使用该Bean 一旦bean不再被使用 则
  • js addEventListener监听scroll滚动条 距离底部一定距离,加载数据,超过最大高度移除监听事件

    测试dmeon testBox height 450px border 1px solid rebeccapurple width 500px color blueviolet overflow y auto 在这里插入代码片 div cl
  • pycharm远程linux服务器的plt.show()不显示

    仅作为记录 博主关闭pycharm重启 即可
  • 数学资源大全

    发信站 水木社区 Wed Apr 30 13 14 00 2008 站内 http www math org cn forums index php showtopic 4427 建议看此贴时 如果找某专题用ie查找 因为网站太多了 好不容
  • Open3D(C++) 法线定向(3)——朝向点云内部

    目录 一 朝向点云内部 二 代码实现 三 结果展示 一 朝向点云内部 如题 算法极其简单 无需做原理介绍 看代码即可 二 代码实现 include
  • 无聊的时候看了下科学计数法..

    作用 当我们要标记或运算某个较大或较小且位数较多时 用科学记数法免去浪费很多空间和时间 概念 科学记数法是一种记数的方法 把一个数表示成a与10的n次幂相乘的形式 这种记数法叫做科学记数法 例 19971400000000 1 99714
  • linux下的npm安装

    NPM Node Package Manager 即node包管理器 是用Javascript编写 最初由Isaac Z Schlueter开发 它会随着node js一起安装 用户可以通过npm把自己设计的模块分发到registry上 也
  • AD设置覆铜的过孔连接方式

    参考链接 https wenku baidu com view 15666e13f18583d049645956 过孔和焊盘有三种连接状态 noconnect 不连接 reliefconnect 十字形连接 directconnect 直接
  • VS2019 C++ SQL Server 数据库连接

    总体来说有VS有两种配置SQL Server的方式 一种是ADO 另一种是ODBC 这两种方式的查询我都有问题 查询到了结果数据不是乱码就是显示在list control上时值变了 我也不知道为什么 ADO 1 什么是ADO 以下ADO概念
  • IDEA简介及使用

    1 Intellij IDEA简介 Eclipse IBM公司开发 1 1 Jetbrains公司介绍 IDEA是JetBrains公司的产品 这家公司总部位于捷克共和国的首都布拉格 开发人员以严谨著称的东欧程序员为主 该公司旗下还有许多其
  • 关于java中实现word转pdf

    1 java中实现word转pdf几种方式如下 1 使用jacob Java COM Bridge 操作offfice的方式 基于这种方式无论是水印还是格式都可以完美转换 但是这个方式都只是基于windos下 但有些项目是需要部署到linu
  • html 页面友情提示,设置网站404页面的正确做法

    核心提示 HTTP 404 错误意味着链接指向的网页不存在 即原始网页的URL失效 这种情况经常会发生 什么是404错误 HTTP 404 错误意味着链接指向的网页不存在 即原始网页的URL失效 这种情况经常会发生 很难避免 比如说 网页U
  • Java解析环保HJ212协议

    文章目录 什么是环保HJ212协议 自己封装了一个基于java的HJ212解析类 解析效果查看 常用的标准码说明 什么是环保HJ212协议 HJ212是由国家环保行业制定的数据传输标准协议 通常是通过TCP IP通讯方式进行数据传输的 数据
  • java如何文档生成目录

    对于现有文档 含标题 使用spire doc去生成目录 由于不是免费版 没有表格行数限制 但第一页开头有个版权声明 只需要用spire生成目录 然后用poi打开它删去第一行声明即可 spire依赖
  • sublime java插件_将SublimeText3打造成简易Java IDE

    简介与优点 使用该教程 你能使你的Sublime Text3可以作为一个精简版的JAVA IDE工具 既可以独立在cmd控制台运行也可以在Sublime自带的控制台运行 运行后不会有乱码 报错后可以在文本框中直接在对应位置显示 基于原有的j
  • Matplotlib绘图(二)

    目录 Matplotlib 二 绘制一元二次方程的曲线y x 2 绘制正弦曲线和余弦曲线 subplot函数 散点图 Matplotlib 二 绘制一元二次方程的曲线y x 2 Matplotlib有很多函数用于绘制各种曲线 其中plot函
  • Openssl 1024bit RSA算法---公私钥获取和处理(一)

    1 简介 使用OpenSSL生成公私钥文件 然后再将文件中的信息读出的操作 由于要对设备升级 需要用到RSA算法对一部分验证信息进行加密 2 使用OpenSSL获取公私钥 我在window系统尝试安装OpenSSL 但是安装不上 我们可以使