EMSA-PKCS1-V1_5-ENCODE及EMSA-PKCS1-V1_5-ENCODE 的实现- just for sha1

本文介绍了一个实现PKCS#1 v1.5填充标准的C语言库,包括编码和解码函数的实现细节。该库使用SHA-1作为默认的摘要算法,并提供了测试代码来验证其正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

头文件:

#ifndef _UPKI__UPKI_PKCS1_PAD_H
#define _UPKI__UPKI_PKCS1_PAD_H
#include <string.h>
#include <stdlib.h>

/* suggested int types */
  typedef unsigned char uint8_t;
  typedef unsigned short uint16_t;
  typedef unsigned int uint32_t;

/* boolean type */
  typedef enum { False, True } Boolean;


enum UPKIErrStatus {

  /** Requested operation completed successfully */
  UPKI_SUCCESS = 0, /* not necessary to force value to zero, but just to be safe */
  /** Message is too long for this function */
  UPKI_ERR_MSG_TOO_LONG,

};

#define MemCpy(s1,s2,n) memcpy((s1),(s2),(n))
#define MemSet(s1,c,n) memset((s1),(c),(n))
#define MemCmp(s1,s2,n) memcmp((s1),(s2),(n))


UPKIErrStatus UPKI_EMSA_PKCS1_v1_5_Encode(int modulusSize, uint8_t * data
          );

uint8_t *UPKI_EMSA_PKCS1_v1_5_Decode(int modulusSize, uint8_t * data
         );

#endif /* _UPKI__UPKI_PKCS1_PAD_H */

 

c文件


#include "upki_pkcs1_pad.h"

const uint8_t SHA1DigestInfo[] = {
  /* SEQUENCE */
  0x30,
  /* length */
  0x21,
  /* Algorithm Identifier */
  /* SEQUENCE */
  0x30,
  /* length */
#ifdef PKCS1_v2_1_BUG
  0x1f,
#else
  0x09,
#endif
  /* OBJECT IDENTIFIER */
  0x06,
  /* Length */
  0x05,
  /* id-SHA1 ::= { iso(1) identified-organisation(3) oiw(14) secsig(3)
   * algorithms(2) 26 */
  0x2b, 0x0e, 0x03, 0x02, 0x1a,
  /* NULL */
  0x05, 0x00,   /* NB: Oscar omits this parameter */
  /* OCTET STRING */
  0x04,
  /* length */
  0x14
};

#define SHA1DigestInfoLen sizeof(SHA1DigestInfo)


#define PKCS1_5_TYPE_01 0x01
#define PKCS1_5_TYPE_02 0x02


/** Encode a message using the EMSA-PKCS-v1_5-Encode method
 *
 * @ingroup upki_provider
 *
 * @param emLen Size of the modulus being used for the padding
 * @param data Buffer to place padded message in
 * @param alg Digest algorithm being used in this padding- just use sha1
 *
 * @pre The message to be encoded is already at
 *   data[emLen - messageLength - 1]
 */
UPKIErrStatus
UPKI_EMSA_PKCS1_v1_5_Encode(int emLen, uint8_t * data)
{
  int startM;
  const uint8_t *digestInfo;
  int digestInfoLen;

  /* EM = 01 || PS || 00 || T, where PS = >8 0xff bytes
   */
    digestInfo = SHA1DigestInfo;
    /* FIXME: Magic numbers */
    startM = emLen - (20 + SHA1DigestInfoLen);
    digestInfoLen = SHA1DigestInfoLen;

 


  /* Check message length */
  if (startM < 10) {
    return UPKI_ERR_MSG_TOO_LONG;
  }

  /* 01 */
  data[0] = PKCS1_5_TYPE_01;

  /* PS */
  MemSet(data + 1, 0xff, startM - 2);

  /* 00 */
  data[startM - 1] = 0;

  /* DigestInfo */
  MemCpy(data + startM, digestInfo, digestInfoLen);

  /* M is already in there */
  return UPKI_SUCCESS;
}

/** Decode a message using the EME-PKCS-v1_5-Decode method
 *
 * @ingroup upki_provider
 *
 * @param emLen Size of the modulus being used for the padding
 * @param data Buffer containing the padded message
 * @param alg Digest algorithm being used in this padding- just use sha1
 *
 * @return offset of the message or NULL on error
 *
 * @pre The message to be encoded is already at
 *   data[emLen - digestSize - 1]
 */
uint8_t *UPKI_EMSA_PKCS1_v1_5_Decode
  (int emLen, uint8_t * data) {
  const uint8_t *digestInfo;
  int i;
  int startM;
  int digestInfoLen;

  /* EM = 01 || PS || 00 || T, where PS = >8 0xff bytes
   */
    digestInfo = SHA1DigestInfo;
    /* FIXME: Magic numbers */
    startM = emLen - (20 + SHA1DigestInfoLen);
    digestInfoLen = SHA1DigestInfoLen;

  /* Check type */
  if (data[0] != PKCS1_5_TYPE_01) {
    return 0;
  }

  /* Check FF */
  for (i = 1; i < startM - 1; i++) {
    if (data[i] != 0xff) {
      return 0;
    }
  }

  /* Check 0 */
  if (data[i] != 0) {
    return 0;
  }

  /* Check digest info */
  if (MemCmp(data + startM, digestInfo, digestInfoLen) != 0) {
    return 0;
  }

  /* All hunky dory, return offset */
  return data + startM + digestInfoLen;
}
 

 

测试代码

#include<stdio.h>
#include "upki_pkcs1_pad.h"

const uint8_t testSHA1[] =
{
  0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
  0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d
};

 

/* Digest algorithm sizes */
 enum DigestAlgorithmSize
 {
    ALG_SHA1_DIGEST_SIZE = 20,
    ALG_MD5_DIGEST_SIZE = 16,
    ALG_MD2_DIGEST_SIZE = 16
  };


int main()
{
  uint8_t buf[128];
  uint8_t *data;
  int errs = 0;

  printf("EMSA-PKCS1-v1_5-Encode with SHA-1/n");
  memcpy(buf + 127 - ALG_SHA1_DIGEST_SIZE, testSHA1, ALG_SHA1_DIGEST_SIZE);
  if (UPKI_EMSA_PKCS1_v1_5_Encode(127, buf) != UPKI_SUCCESS)
  {
    printf("failed/n");
  } else
  {
    printf("ok/n");
  }

  printf("EMSA-PKCS1-v1_5-Decode with SHA-1/n");
  data = UPKI_EMSA_PKCS1_v1_5_Decode(127, buf);
  if (!data || memcmp(data, testSHA1, ALG_SHA1_DIGEST_SIZE) != 0)
  {
    printf("failed/n");
    errs++;
  } else
  {
    printf("ok/n");
  }


 
  while(1);
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值