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

📄 rsa.cpp

📁 RSA加密解密的算法例程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 * Returns 0 if successful, or ERR_RSA_DECRYPT_FAILED
 */
int rsa_pkcs1_decrypt( rsa_context *ctx,
                       uchar *input,  uint  ilen,
                       uchar *output, uint *olen )
{
    uchar *p, tmp[512];

    if( ilen != ctx->len || ilen < 48 || ilen > 512 )
        return( ERR_RSA_DECRYPT_FAILED );

    if( rsa_private( ctx, input, ilen, tmp, ilen ) != 0 )
        return( ERR_RSA_DECRYPT_FAILED );

    p = tmp;

    if( *p++ != 0 || *p++ != RSA_CRYPT )
        return( ERR_RSA_DECRYPT_FAILED );

    while( *p != 0 )
    {
        if( p >= tmp + ilen - 1 )
            return( ERR_RSA_DECRYPT_FAILED );
        p++;
    }
    p++;

    if( *olen < ilen - (uint)(p - tmp) )
        return( ERR_RSA_DECRYPT_FAILED );

    *olen = ilen - (uint)(p - tmp);
    memcpy( output, p, *olen );

    return( 0 );
}

/*
 * Perform a private RSA to sign a message digest
 *
 *      ctx     points to an RSA private key
 *      hash    buffer holding the message digest
 *      alg_id  must be set to RSA_MD2/4/5 or RSA_SHA1
 *      sig     buffer that will hold the ciphertext
 *      siglen  must be the same as the modulus size
 *              (for example, 128 if RSA-1024 is used)
 *
 * Returns 0 if successful, or ERR_RSA_SIGN_FAILED
 */
int rsa_pkcs1_sign( rsa_context *ctx,
                    uchar *hash, int alg_id,
                    uchar *sig, uint siglen )
{
    int nb_pad;
    uchar *p = sig;

    if( siglen != ctx->len || siglen < 48 )
        return( ERR_RSA_SIGN_FAILED );

    switch( alg_id )
    {
        case RSA_MD2:
        case RSA_MD4:
        case RSA_MD5:
            nb_pad = siglen - 3 - 34;
            break;

        case RSA_SHA1:
            nb_pad = siglen - 3 - 35;
            break;

        default:
            return( ERR_RSA_SIGN_FAILED );
    }

    if( nb_pad < 8 )
        return( ERR_RSA_SIGN_FAILED );

    *p++ = 0;
    *p++ = RSA_SIGN;

    memset( p, 0xFF, nb_pad );
    p += nb_pad;
    *p++ = 0;

    switch( alg_id )
    {
        case RSA_MD2:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 2; break;

        case RSA_MD4:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 4; break;

        case RSA_MD5:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 5; break;

        case RSA_SHA1:
            memcpy( p, ASN1_HASH_SHA1, 15 );
            memcpy( p + 15, hash, 20 );
            break;

        default:
            return( ERR_RSA_SIGN_FAILED );
    }

    if( rsa_private( ctx, sig, siglen, sig, siglen ) != 0 )
        return( ERR_RSA_SIGN_FAILED );

    return( 0 );
}

/*
 * Perform a public RSA and check the message digest.
 *
 *      ctx     points to an RSA public key
 *      hash    buffer holding the message digest
 *      alg_id  must be set to RSA_MD{2,4,5} or RSA_SHA1
 *      sig     buffer holding the ciphertext
 *      siglen  must be the same as the modulus size
 *
 * Returns 0 if successful, or ERR_RSA_VERIFY_FAILED
 */
int rsa_pkcs1_verify( rsa_context *ctx,
                      uchar *hash, int alg_id,
                      uchar *sig, uint siglen )
{
    int len;
    uchar *p, c, tmp[512];

    if( siglen != ctx->len || siglen < 48 || siglen > 512 )
        return( ERR_RSA_VERIFY_FAILED );

    if( rsa_public( ctx, sig, siglen, tmp, siglen ) != 0 )
        return( ERR_RSA_VERIFY_FAILED );

    p = tmp;

    if( *p++ != 0 || *p++ != RSA_SIGN )
        return( ERR_RSA_VERIFY_FAILED );

    while( *p != 0 )
    {
        if( p >= tmp + siglen - 1 || *p != 0xFF )
            return( ERR_RSA_VERIFY_FAILED );
        p++;
    }
    p++;

    len = siglen - (uint)( p - tmp );

    if( len == 34 )
    {
        c = p[13];
        p[13] = 0;
        if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
            return( ERR_RSA_VERIFY_FAILED );

        if( ( c == 2 && alg_id == RSA_MD2 ) ||
            ( c == 4 && alg_id == RSA_MD4 ) ||
            ( c == 5 && alg_id == RSA_MD5 ) )
        {
            if( memcmp( p + 18, hash, 16 ) == 0 ) 
                return( 0 );
        }
    }

    if( len == 35 && alg_id == RSA_SHA1 )
    {
        if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
            memcmp( p + 15, hash, 20 ) == 0 )
            return( 0 );
    }

    return( ERR_RSA_VERIFY_FAILED );
}

/*
 * Free the components of an RSA key.
 */
void rsa_free( rsa_context *ctx )
{
	debug_print(&ctx->N);	//32
	debug_print(&ctx->E);	//1
	debug_print(&ctx->D);	//32
	debug_print(&ctx->P);	//16
	debug_print(&ctx->Q);	//16
	debug_print(&ctx->DP);	//16
	debug_print(&ctx->DQ);	//16
	debug_print(&ctx->QP);	//16
	mpi_free( &ctx->N,  &ctx->E,  &ctx->D,
              &ctx->P,  &ctx->Q,  &ctx->DP,
              &ctx->DQ, &ctx->QP, NULL );
}

#ifdef SELF_TEST

#include "md5.h"

uchar plaintext[] =
    "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
    "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD";

#define PTLEN   24
#define CTLEN  128

/*
 * Checkup routine
 */
int rsa_self_test( void )
{
    uint len;
    rsa_context rsa;
    uchar md5sum[16];
    uchar decrypted[PTLEN];
    uchar ciphertext[CTLEN];

    memset( &rsa, 0, sizeof( rsa ) );

    rsa.len = 128;

    mpi_read( &rsa.N , "9292758453063D803DD603D5E777D788" \
                       "8ED1D5BF35786190FA2F23EBC0848AEA" \
                       "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
                       "7130B9CED7ACDF54CFC7555AC14EEBAB" \
                       "93A89813FBF3C4F8066D2D800F7C38A8" \
                       "1AE31942917403FF4946B0A83D3D3E05" \
                       "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
                       "5E94BB77B07507233A0BC7BAC8F90F79", 16 );

    mpi_read( &rsa.E , "10001", 16 );
    mpi_read( &rsa.D , "24BF6185468786FDD303083D25E64EFC" \
                       "66CA472BC44D253102F8B4A9D3BFA750" \
                       "91386C0077937FE33FA3252D28855837" \
                       "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
                       "DF79C5CE07EE72C7F123142198164234" \
                       "CABB724CF78B8173B9F880FC86322407" \
                       "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
                       "071513A1E85B5DFA031F21ECAE91A34D", 16 );

    mpi_read( &rsa.P , "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
                       "2C01CAD19EA484A87EA4377637E75500" \
                       "FCB2005C5C7DD6EC4AC023CDA285D796" \
                       "C3D9E75E1EFC42488BB4F1D13AC30A57", 16 );
    mpi_read( &rsa.Q , "C000DF51A7C77AE8D7C7370C1FF55B69" \
                       "E211C2B9E5DB1ED0BF61D0D9899620F4" \
                       "910E4168387E3C30AA1E00C339A79508" \
                       "8452DD96A9A5EA5D9DCA68DA636032AF", 16 );

    mpi_read( &rsa.DP, "C1ACF567564274FB07A0BBAD5D26E298" \
                       "3C94D22288ACD763FD8E5600ED4A702D" \
                       "F84198A5F06C2E72236AE490C93F07F8" \
                       "3CC559CD27BC2D1CA488811730BB5725", 16 );
    mpi_read( &rsa.DQ, "4959CBF6F8FEF750AEE6977C155579C7" \
                       "D8AAEA56749EA28623272E4F7D0592AF" \
                       "7C1F1313CAC9471B5C523BFE592F517B" \
                       "407A1BD76C164B93DA2D32A383E58357", 16 );
    mpi_read( &rsa.QP, "9AE7FBC99546432DF71896FC239EADAE" \
                       "F38D18D2B2F0E2DD275AA977E2BF4411" \
                       "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
                       "A74206CEC169D74BF5A8C50D6F48EA08", 16 );

    printf( "  RSA key validation: " );

    if( rsa_check_pubkey(  &rsa ) != 0 ||
        rsa_check_privkey( &rsa ) != 0 )
    {
        printf( "failed\n" );
        return( 1 );
    }

    printf( "passed\n  PKCS#1 encryption : " );

    if( rsa_pkcs1_encrypt( &rsa, plaintext,  PTLEN,
                                 ciphertext, CTLEN ) != 0 )
    {
        printf( "failed\n" );
        return( 1 );
    }

    printf( "passed\n  PKCS#1 decryption : " );

    len = sizeof( decrypted );

    if( rsa_pkcs1_decrypt( &rsa, ciphertext, CTLEN,
                                 decrypted,  &len ) != 0 ||
        memcmp( decrypted, plaintext, len ) != 0 )
    {
        printf( "failed\n" );
        return( 1 );
    }

    printf( "passed\n  PKCS#1 data sign  : " );

    md5_csum( plaintext, PTLEN, md5sum );

    if( rsa_pkcs1_sign( &rsa, md5sum, RSA_MD5,
                        ciphertext, CTLEN ) != 0 )
    {
        printf( "failed\n" );
        return( 1 );
    }

    printf( "passed\n  PKCS#1 sig. verify: " );

    if( rsa_pkcs1_verify( &rsa, md5sum, RSA_MD5,
                          ciphertext, CTLEN ) != 0 )
    {
        printf( "failed\n" );
        return( 1 );
    }

    printf( "passed\n\n" );
//	add by lyt
	rsa_free(&rsa);
//
    return( 0 );
}
#else
int rsa_self_test( void )
{
    printf( "RSA self-test not available\n\n" );
    return( 1 );
}
#endif

⌨️ 快捷键说明

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