Certificate 如何从SHA1散列中可靠地获得非负序列号?

Certificate 如何从SHA1散列中可靠地获得非负序列号?,certificate,serial-number,cng,Certificate,Serial Number,Cng,我正在使用CNG生成证书的序列号。我的算法采用证书颁发机构的通用名称,附加10个随机字节,然后计算该字节的SHA1哈希。SHA1散列的长度始终为20字节,我将其用作序列号 问题!就OpenSSL而言,我无法从该算法中获得可靠的正数。负序列号会导致OpenSSL出现问题。那么,如何确保OpenSSL始终将我的20个字节视为“正”序列号呢 例如,这些序列号: DA7DB14CBC79401B642FD77806B54E21B0012BBE1 f67604707a861fac55fbef8a5571a

我正在使用CNG生成证书的序列号。我的算法采用证书颁发机构的通用名称,附加10个随机字节,然后计算该字节的SHA1哈希。SHA1散列的长度始终为20字节,我将其用作序列号

问题!就OpenSSL而言,我无法从该算法中获得可靠的正数。负序列号会导致OpenSSL出现问题。那么,如何确保OpenSSL始终将我的20个字节视为“正”序列号呢

例如,这些序列号:

DA7DB14CBC79401B642FD77806B54E21B0012BBE1 f67604707a861fac55fbef8a5571ab8284e761bd 7d8df1b0b62c284ad12fd1eaadfb18dd4c9c91ba 8588ea1034c6c5a23b1f5cf9689e63baf10775a9 169ad01b41f6e5108d64d70bb8de25da475e02b5 89ff69bc06ec5a93c9e11e71a990f7e8ee0a9d3d 6DBD23A8655C9627A8D241D48A909AE7823DC1C

当我将它们放入证书吊销列表中时生成此输出,这是不可接受的:

被吊销的证书: 序列号:-25824EB34386BFE49BD02887F94AB1DE4FED441F 撤销日期:2018年3月14日21:47:02 GMT 序列号:-0989FB8F8579E053AA041075AA8E547D7B189E43 撤销日期:2018年3月14日21:47:02 GMT 编号:00 撤销日期:2018年3月14日21:47:02 GMT 序列号:-7A7715EFCB393A5DC4E0A30697619C450EF88A57 撤销日期:2018年3月14日21:47:02 GMT 序列号:169AD01B41F6E5108D64D70BB8DE25DA475E02B5 撤销日期:2018年3月14日21:47:02 GMT 序列号:-76009643F913A56C361EE18E566F081711F562C3 撤销日期:2018年3月14日21:47:02 GMT 序列号:6DBD23A8655C9627A8D241D48A909AE7823DC1C 撤销日期:2018年3月14日21:47:02 GMT

有没有办法屏蔽一个字节的一部分,使其始终为正?还有,第三个序列号被解释为零有什么原因吗

用于生成序列号的代码示例:

void CERTSTORE::GetSerialNumber(
eAction eActionTaken,
std::string sCACN, 
std::vector<BYTE> & vSerialNumber
)
{
    NTSTATUS statusBCryptOpenAlgorithmProvider_Hash;
    NTSTATUS statusBCryptOpenAlgorithmProvider_RNG;
    NTSTATUS statusBCryptGenRandom;
    NTSTATUS statusBCryptHash;
    BCRYPT_ALG_HANDLE hRandNumAlg;
    BCRYPT_ALG_HANDLE hHashAlg;
    DWORD dwHash = 20;
    BYTE bRandomBytes[10];
    std::vector<BYTE> vBytesToBeHashed(
        (BYTE)sCACN.c_str(),
        sCACN.length()
    );

    //open algorithm provider to get random number generator
    statusBCryptOpenAlgorithmProvider_RNG = BCryptOpenAlgorithmProvider(
        &hRandNumAlg,
        BCRYPT_RNG_ALGORITHM,
        MS_PRIMITIVE_PROVIDER,
        0
    );

    if (0 != statusBCryptOpenAlgorithmProvider_RNG)
    {
        throw ERRORSTRING(
            eActionTaken,
            eSubAction::eSubAction_OPENALGPROV,
            eMajorErrorCode::eMajorErrorCode_RUNTIMEERROR,
            eMinorErrorCode::eMinorErrorCode_UKNNTSTATUS,
            statusBCryptOpenAlgorithmProvider_RNG
        );
    }

    statusBCryptGenRandom = BCryptGenRandom(
        hRandNumAlg,
        bRandomBytes,
        sizeof(bRandomBytes),
        0
    );

    if (0 != statusBCryptGenRandom)
    {
        BCryptCloseAlgorithmProvider(hRandNumAlg, 0);
        throw ERRORSTRING(
            eActionTaken,
            eSubAction::eSubAction_GENRANDOM,
            eMajorErrorCode::eMajorErrorCode_RUNTIMEERROR,
            eMinorErrorCode::eMinorErrorCode_UKNNTSTATUS,
            statusBCryptGenRandom
        );
    }

    BCryptCloseAlgorithmProvider(hRandNumAlg, 0);

    for (int iRandByteCounter = 0; iRandByteCounter < sizeof(bRandomBytes); iRandByteCounter++)
    {
        vBytesToBeHashed.push_back(
            bRandomBytes[iRandByteCounter]
        );
    }

    statusBCryptOpenAlgorithmProvider_Hash = BCryptOpenAlgorithmProvider(
        &hHashAlg,
        BCRYPT_SHA1_ALGORITHM,
        MS_PRIMITIVE_PROVIDER,
        0
    );

    if (0 != statusBCryptOpenAlgorithmProvider_Hash)
    {
        throw ERRORSTRING(
            eActionTaken,
            eSubAction::eSubAction_OPENALGPROV,
            eMajorErrorCode::eMajorErrorCode_RUNTIMEERROR,
            eMinorErrorCode::eMinorErrorCode_UKNNTSTATUS,
            statusBCryptOpenAlgorithmProvider_Hash
        );
    }

    try
    {
        vSerialNumber.assign(
            dwHash,
            NULL
        );
    }
    catch (std::exception & ex)
    {
        throw ERRORSTRING(
            eActionTaken,
            eSubAction::eSubAction_CRYPTHASH,
            eMajorErrorCode::eMajorErrorCode_RUNTIMEERROR,
            eMinorErrorCode::eMinorErrorCode_MEMORYALLOCATION,
            0
        );
    }

    statusBCryptHash = BCryptHash(
        hHashAlg,
        NULL,
        0,
        &vBytesToBeHashed[0],
        vBytesToBeHashed.size(),
        &vSerialNumber[0],
        dwHash
    );

    if (0 != statusBCryptHash)
    {
        BCryptCloseAlgorithmProvider(hHashAlg, 0);
        throw ERRORSTRING(
            eActionTaken,
            eSubAction::eSubAction_CRYPTHASH,
            eMajorErrorCode::eMajorErrorCode_RUNTIMEERROR,
            eMinorErrorCode::eMinorErrorCode_UKNNTSTATUS,
            statusBCryptHash
        );
    }

    BCryptCloseAlgorithmProvider(hHashAlg, 0);
}
void CERTSTORE::GetSerialNumber(
采取的行动,
字符串sCACN,
std::vector和vSerialNumber
)
{
NTSTATUS StatusBCryptopPenalgorithmProvider\u散列;
NTSTATUS Status CryptoPenalgorithmProvider\u RNG;
NTSTATUS statusBCryptGenRandom;
NTSTATUS statusBCryptHash;
b控制手柄和螺母;
BCRYPT_ALG_HANDLE hHashAlg;
DWORD dwHash=20;
字节bRandomBytes[10];
std::vector vBytesToBeHashed(
(字节)sCACN.c_str(),
sCACN.length()
);
//打开算法提供程序以获取随机数生成器
statusBCryptOpenAlgorithmProvider\u RNG=BCryptOpenAlgorithmProvider(
&赫兰努马尔格,
BCRYPT_RNG_算法,
MS_原语_提供者,
0
);
如果(0!=statusBCryptOpenAlgorithmProvider\u RNG)
{
抛出错误字符串(
采取的行动,
eSubAction::eSubAction_OPENALGPROV,
eMajorErrorCode::eMajorErrorCode\u运行时错误,
EminoreErrorCode::EminoreErrorCode_UKNNTSTATUS,
状态密码算法提供程序\u RNG
);
}
statusBCryptGenRandom=BCryptGenRandom(
赫兰努马尔格,
bRandomBytes,
sizeof(bRandomBytes),
0
);
如果(0!=statusBCryptGenRandom)
{
BCryptCloseAlgorithmProvider(hRandNumAlg,0);
抛出错误字符串(
采取的行动,
eSubAction::eSubAction_GENRANDOM,
eMajorErrorCode::eMajorErrorCode\u运行时错误,
EminoreErrorCode::EminoreErrorCode_UKNNTSTATUS,
statusBCryptGenRandom
);
}
BCryptCloseAlgorithmProvider(hRandNumAlg,0);
for(int-iRandByteCounter=0;iRandByteCounter
取决于超出该点使用的API,20个字节要么是小端,要么是大端。既然你说第三个是负数,那么它似乎是小endian

Little Endian修复:

vSerialNumber[19] &= 0x7F
vSerialNumber[0] &= 0x7F;
大端修复:

vSerialNumber[19] &= 0x7F
vSerialNumber[0] &= 0x7F;
“呃,只要工作”修正:


您已将熵减少了一(或两)位,但仍在安全范围内。

根据超出该点使用的API,20个字节可以是小端字节,也可以是大端字节。既然你说第三个是负数,那么它似乎是小endian

Little Endian修复:

vSerialNumber[19] &= 0x7F
vSerialNumber[0] &= 0x7F;
大端修复:

vSerialNumber[19] &= 0x7F
vSerialNumber[0] &= 0x7F;
“嗯,只是