⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_enhanc.c

📁 常用的密码算法
💻 C
📖 第 1 页 / 共 3 页
字号:
unsigned char *encryptedKey;                      /* encoded, encrypted key */
unsigned int *encryptedKeyLen;                                    /* length */
unsigned char *encryptedSignature;          /* encoded, encrypted signature */
unsigned int *encryptedSignatureLen;                              /* length */
unsigned char iv[8];                           /* DES initialization vector */
unsigned char *content;                                          /* content */
unsigned int contentLen;                               /* length of content */
int digestAlgorithm;                           /* message-digest algorithms */
R_RSA_PUBLIC_KEY *publicKey;                  /* recipient's RSA public key */
R_RSA_PRIVATE_KEY *privateKey;                  /* signer's RSA private key */
R_RANDOM_STRUCT *randomStruct;                          /* random structure */
{
  R_ENVELOPE_CTX context;
  R_RSA_PUBLIC_KEY *publicKeys[1];
  int status;
  unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
    signature[MAX_SIGNATURE_LEN], *encryptedKeys[1];
  unsigned int signatureLen, encryptedKeyBlockLen;
  
  do {
    if ((status = R_SignBlock
         (signature, &signatureLen, content, contentLen, digestAlgorithm,
          privateKey)) != 0)
      break;

    publicKeys[0] = publicKey;
    encryptedKeys[0] = encryptedKeyBlock;
    if ((status = R_SealInit
         (&context, encryptedKeys, &encryptedKeyBlockLen, iv, 1, publicKeys,
          EA_DES_CBC, randomStruct)) != 0)
      break;

    R_EncodePEMBlock 
      (encryptedKey, encryptedKeyLen, encryptedKeyBlock,
       encryptedKeyBlockLen);

    EncryptPEMUpdateFinal
      (&context, encryptedContent, encryptedContentLen, content,
       contentLen);
    
    EncryptPEMUpdateFinal
      (&context, encryptedSignature, encryptedSignatureLen, signature,
       signatureLen);
  } while (0);
  
  /* Zeroize sensitive information.
   */
  R_memset ((POINTER)&context, 0, sizeof (context));
  R_memset ((POINTER)signature, 0, sizeof (signature));

  return (status);
}

int R_OpenPEMBlock
  (content, contentLen, encryptedContent, encryptedContentLen, encryptedKey,
   encryptedKeyLen, encryptedSignature, encryptedSignatureLen,
   iv, digestAlgorithm, privateKey, publicKey)
unsigned char *content;                                          /* content */
unsigned int *contentLen;                              /* length of content */
unsigned char *encryptedContent;              /* encoded, encrypted content */
unsigned int encryptedContentLen;                                 /* length */
unsigned char *encryptedKey;                      /* encoded, encrypted key */
unsigned int encryptedKeyLen;                                     /* length */
unsigned char *encryptedSignature;          /* encoded, encrypted signature */
unsigned int encryptedSignatureLen;                               /* length */
unsigned char iv[8];                           /* DES initialization vector */
int digestAlgorithm;                           /* message-digest algorithms */
R_RSA_PRIVATE_KEY *privateKey;               /* recipient's RSA private key */
R_RSA_PUBLIC_KEY *publicKey;                     /* signer's RSA public key */
{
  R_ENVELOPE_CTX context;
  int status;
  unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
    signature[MAX_SIGNATURE_LEN];
  unsigned int encryptedKeyBlockLen, signatureLen;
  
  if (encryptedKeyLen > MAX_PEM_ENCRYPTED_KEY_LEN)
    return (RE_KEY_ENCODING);
  
  if (encryptedSignatureLen > MAX_PEM_ENCRYPTED_SIGNATURE_LEN)
    return (RE_SIGNATURE_ENCODING);
  
  do {
    if (R_DecodePEMBlock 
        (encryptedKeyBlock, &encryptedKeyBlockLen, encryptedKey,
         encryptedKeyLen) != 0) {
      status = RE_KEY_ENCODING;
      break;
    }

    if ((status = R_OpenInit
         (&context, EA_DES_CBC, encryptedKeyBlock, encryptedKeyBlockLen,
          iv, privateKey)) != 0)
      break;

    if ((status = DecryptPEMUpdateFinal
         (&context, content, contentLen, encryptedContent,
          encryptedContentLen)) != 0) {
      if ((status == RE_LEN || status == RE_ENCODING))
        status = RE_CONTENT_ENCODING;
      else
        status = RE_KEY;
      break;
    }
    
    if (status = DecryptPEMUpdateFinal
        (&context, signature, &signatureLen, encryptedSignature,
         encryptedSignatureLen)) {
      if ((status == RE_LEN || status == RE_ENCODING))
        status = RE_SIGNATURE_ENCODING;
      else
        status = RE_KEY;
      break;
    }

    if ((status = R_VerifyBlockSignature
         (content, *contentLen, signature, signatureLen, digestAlgorithm,
          publicKey)) != 0)
      break;
  } while (0);
  
  /* Zeroize sensitive information.
   */
  R_memset ((POINTER)&context, 0, sizeof (context));
  R_memset ((POINTER)signature, 0, sizeof (signature));

  return (status);
}

int R_DigestBlock (digest, digestLen, block, blockLen, digestAlgorithm)
unsigned char *digest;                                    /* message digest */
unsigned int *digestLen;                        /* length of message digest */
unsigned char *block;                                              /* block */
unsigned int blockLen;                                   /* length of block */
int digestAlgorithm;                            /* message-digest algorithm */
{
  R_DIGEST_CTX context;
  int status;

  do {
    if ((status = R_DigestInit (&context, digestAlgorithm)) != 0)
      break;
    if ((status = R_DigestUpdate (&context, block, blockLen)) != 0)
      break;
    if ((status = R_DigestFinal (&context, digest, digestLen)) != 0)
      break;
  } while (0);

  /* Zeroize sensitive information. */
  R_memset ((POINTER)&context, 0, sizeof (context));

  return (status);
}

/* Assumes digestAlgorithm is DA_MD2 or DA_MD5 and digest length is 16.
 */
static void R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest)
unsigned char *digestInfo;                           /* DigestInfo encoding */
int digestAlgorithm;                            /* message-digest algorithm */
unsigned char *digest;                                    /* message digest */
{
  R_memcpy 
    ((POINTER)digestInfo, (POINTER)DIGEST_INFO_A, DIGEST_INFO_A_LEN);
  
  digestInfo[DIGEST_INFO_A_LEN] =
    (digestAlgorithm == DA_MD2) ? (unsigned char)2 : (unsigned char)5;

  R_memcpy 
    ((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1], (POINTER)DIGEST_INFO_B,
     DIGEST_INFO_B_LEN);
  
  R_memcpy 
    ((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN],
     (POINTER)digest, 16);
}

/* Call SealUpdate and SealFinal on the input and ASCII recode.
 */
static void EncryptPEMUpdateFinal
  (context, output, outputLen, input, inputLen)
R_ENVELOPE_CTX *context;
unsigned char *output;                          /* encrypted, encoded block */
unsigned int *outputLen;                                /* length of output */
unsigned char *input;                                   /* block to encrypt */
unsigned int inputLen;                                            /* length */
{
  unsigned char encryptedPart[24];
  unsigned int i, lastPartLen, tempLen, len;

  /* Choose a buffer size of 24 bytes to hold the temporary encrypted output
       which will be encoded.
     Encrypt and encode as many 24-byte blocks as possible.
   */
  for (i = 0; i < inputLen / 24; ++i) {
    /* Assume part out length will equal part in length since it is
         a multiple of 8.  Also assume no error output. */
    R_SealUpdate (context, encryptedPart, &tempLen, &input[24*i], 24);

    /* len is always 32 */
    R_EncodePEMBlock (&output[32*i], &tempLen, encryptedPart, 24);
  }
  
  /* Encrypt the last part into encryptedPart.
   */  
  R_SealUpdate
    (context, encryptedPart, &lastPartLen, &input[24*i], inputLen - 24*i);
  R_SealFinal (context, encryptedPart + lastPartLen, &len);
  lastPartLen += len;

  R_EncodePEMBlock (&output[32*i], &len, encryptedPart, lastPartLen);
  *outputLen = 32*i + len;

  /* Zeroize sensitive information.
   */
  R_memset ((POINTER)encryptedPart, 0, sizeof (encryptedPart));
}

static int DecryptPEMUpdateFinal (context, output, outputLen, input, inputLen)
R_ENVELOPE_CTX *context;
unsigned char *output;                          /* decoded, decrypted block */
unsigned int *outputLen;                                /* length of output */
unsigned char *input;                           /* encrypted, encoded block */
unsigned int inputLen;                                            /* length */
{
  int status;
  unsigned char encryptedPart[24];
  unsigned int i, len;
  
  do {
    /* Choose a buffer size of 24 bytes to hold the temporary decoded output
         which will be decrypted.
       Decode and decrypt as many 32-byte input blocks as possible.
     */
    *outputLen = 0;
    for (i = 0; i < inputLen/32; i++) {
      /* len is always 24 */
      if ((status = R_DecodePEMBlock
           (encryptedPart, &len, &input[32*i], 32)) != 0)
        break;

      /* Excpect no error return */
      R_OpenUpdate (context, output, &len, encryptedPart, 24);
      output += len;
      *outputLen += len;
    }
    if (status)
      break;

    /* Decode the last part */  
    if ((status = R_DecodePEMBlock
         (encryptedPart, &len, &input[32*i], inputLen - 32*i)) != 0)
      break;

    /* Decrypt the last part.
     */
    R_OpenUpdate (context, output, &len, encryptedPart, len);
    output += len;
    *outputLen += len;
    if ((status = R_OpenFinal (context, output, &len)) != 0)
      break;
    *outputLen += len;
  } while (0);

  /* Zeroize sensitive information.
   */
  R_memset ((POINTER)&context, 0, sizeof (context));
  R_memset ((POINTER)encryptedPart, 0, sizeof (encryptedPart));

  return (status);
}

static int CipherInit (context, encryptionAlgorithm, key, iv, encrypt)
R_ENVELOPE_CTX *context;
int encryptionAlgorithm;
unsigned char *key;                                              /* DES key */
unsigned char *iv;                             /* DES initialization vector */
int encrypt;                     /* encrypt flag (1 = encrypt, 0 = decrypt) */
{
  switch (encryptionAlgorithm) {
  case EA_DES_CBC:
    DES_CBCInit (&context->cipherContext.des, key, iv, encrypt);
    return (0);
  case EA_DESX_CBC:
    DESX_CBCInit (&context->cipherContext.desx, key, iv, encrypt);
    return (0);
  case EA_DES_EDE2_CBC:
  case EA_DES_EDE3_CBC:
    DES3_CBCInit (&context->cipherContext.des3, key, iv, encrypt);
    return (0);

  default:
    return (RE_ENCRYPTION_ALGORITHM);
  }
}

/* Assume len is a multiple of 8.
 */
static void CipherUpdate (context, output, input, len)
R_ENVELOPE_CTX *context;
unsigned char *output;                                      /* output block */
unsigned char *input;                                        /* input block */
unsigned int len;                      /* length of input and output blocks */
{
  if (context->encryptionAlgorithm == EA_DES_CBC)
    DES_CBCUpdate (&context->cipherContext.des, output, input, len);
  else if (context->encryptionAlgorithm == EA_DESX_CBC)
    DESX_CBCUpdate (&context->cipherContext.desx, output, input, len);
  else
    DES3_CBCUpdate (&context->cipherContext.des3, output, input, len);
}

static void CipherRestart (context)
R_ENVELOPE_CTX *context;
{
  if (context->encryptionAlgorithm == EA_DES_CBC)
    DES_CBCRestart (&context->cipherContext.des);
  else if (context->encryptionAlgorithm == EA_DESX_CBC)
    DESX_CBCRestart (&context->cipherContext.desx);
  else
    DES3_CBCRestart (&context->cipherContext.des3);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -