Closed yebin-yu closed 6 months ago
当前签名代码
void SM2_gmSig2OpensslSig(ECCSIGNATUREBLOB *sigBlob, unsigned char **sig, size_t *len)
{
BIGNUM *rB=NULL;
BIGNUM *sB=NULL;
BYTE *r = sigBlob->r+32;
BYTE *s = sigBlob->s+32;
rB = BN_bin2bn(r, 32, NULL);
if(rB == NULL) {return NULL;}
sB = BN_bin2bn(s, 32, NULL);
if(sB == NULL) {return NULL;}
ECDSA_SIG *ecdsaSig = ECDSA_SIG_new();
if (ecdsaSig == NULL) {return NULL;}
if(ECDSA_SIG_set0(ecdsaSig, rB, sB) != 1) {
return NULL;
}
unsigned char* sig_temp = NULL;
int sigLen = i2d_ECDSA_SIG(ecdsaSig, sig);
// *sig = sig_temp;
printf("%s", *sig);
*len = sigLen;
}
int EVP_Digest(const void *data, size_t count,
unsigned char *md, unsigned int *size, const EVP_MD *type,
ENGINE *impl, struct sshkey *sign_key)
{
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
int ret;
EVP_PKEY *key_sm2 = NULL;
if ((key_sm2 = EVP_PKEY_new()) == NULL) {
return SSH_ERR_ALLOC_FAIL;
}
if ((EVP_PKEY_set1_EC_KEY(key_sm2, sign_key->ecdsa)) != 1) {
ret = SSH_ERR_INTERNAL_ERROR;
return 0;
}
if (ctx == NULL)
return 0;
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
ret = EVP_DigestInit_ex(ctx, type, impl)
&& EVP_DigestUpdate(ctx, data, count)
&& EVP_DigestFinal_ex(ctx, md, size);
EVP_MD_CTX_free(ctx);
return ret;
}
static int
init_ukey_container(HCONTAINER *hcontainer)
{
HANDLE hdev = NULL;
ULONG ulRslt = SAR_OK;
// 枚举获取设备名,这里的逻辑应该是自动获取然后赋值
// ukey上获取到的值应该为:3DC2105010CFD4C62A42E5375DA38B9
char szDevName[256] = {0};
ULONG ulDevNameLen = 256;
ulRslt = SKF_EnumDev(TRUE, szDevName, &ulDevNameLen);
printf("szDevName: %s \n", szDevName);
if (ulRslt != SAR_OK) {
debug("SKF_EnumDev ERROR \n");
return 1;
}
// 连接设备
ulRslt = SKF_ConnectDev(szDevName, &hdev);
if (ulRslt != SAR_OK) {
debug("SKF_ConnectDev ERROR \n");
return 1;
}
// 获取application,这里的逻辑应该是自动获取然后赋值
// ukey上获取到的值应该为:GM3000RSA
char appName[256] = {0};
ULONG appnameLen = 256;
ulRslt = SKF_EnumApplication(hdev, appName, &appnameLen);
printf("appName: %s\n", appName);
if (ulRslt != SAR_OK) {
debug("SKF_EnumApplication ERROR \n");
return 1;
}
// 打开应用
HANDLE happ;
ulRslt = SKF_OpenApplication(hdev, appName, &happ);
if (ulRslt != SAR_OK) {
debug("SKF_OpenApplication ERROR \n");
return 1;
}
// 验证pin码
char pinStr[32];
ULONG retryCntMax = 3;
ULONG currentRetryCnt = 0;
printf("UKEY pin:");
scanf("%s", pinStr);
ulRslt = SKF_VerifyPIN(happ, USER_TYPE, pinStr, &retryCntMax);
while (ulRslt != SAR_OK && currentRetryCnt++ < retryCntMax) {
sleep(2); // 防止暴力破解,等待两秒
printf("UKEY pin again:");
scanf("%s", pinStr);
ulRslt = SKF_VerifyPIN(happ, USER_TYPE, pinStr, &retryCntMax);
}
if (ulRslt != SAR_OK) {
debug("SKF_VerifyPIN ERROR \n");
return 1;
}
// 获取容器名
// ukey上获取到的值应该为:sm2
char containerName[256] = {0};
ULONG containerNameLen = 256;
ulRslt = SKF_EnumContainer(happ, containerName, &containerNameLen);
printf("containerName: %s\n", containerName);
if (ulRslt != SAR_OK) {
debug("SKF_EnumContainer ERROR \n");
return 1;
}
// 打开容器
ulRslt = SKF_OpenContainer(happ, containerName, hcontainer);
if (ulRslt != SAR_OK) {
debug("SKF_OpenContainer ERROR \n");
return 1;
}
return SAR_OK;
}
static int
ukey_get_sig(const u_char *data, size_t datalen, u_char **sig, size_t *slen, struct sshkey *sign_key)
{
// get container handle
ULONG ulRslt = SAR_OK;
HCONTAINER container = NULL;
if (init_ukey_container(&container) != 0) {
debug("init_ukey_container ERROR \n");
return 1;
}
// hash
unsigned char hashRslt[32] = {0};
int hashLen;
if(1 != EVP_Digest(data, datalen, hashRslt, &hashLen, EVP_sm3(), NULL, sign_key)) {
debug("EVP_Digest ERROR \n");
return 1;
}
// sign
ECCSIGNATUREBLOB stSign = {0};
ulRslt = SKF_ECCSignData(container, hashRslt, hashLen, &stSign);
if (ulRslt != SAR_OK) {
debug("SKF_ECCSignData ERROR \n");
return 1;
}
SM2_gmSig2OpensslSig(&stSign, sig, slen);
return 0;
}
hash的部分用ukey的代码代替
// hash
unsigned char hashRslt[32] = {0};
int hashLen;
ECCPUBLICKEYBLOB *blob = (ECCPUBLICKEYBLOB *)buf;
const unsigned char *sm2_id = (const unsigned char *)"1234567812345678";
HANDLE phHash = NULL;
SKF_DigestInit(hDev, SGD_SM3, blob, sm2_id, 16, &phHash);
SKF_Digest(phHash, data, datalen, hashRslt, &hashLen);
// if(1 != EVP_Digest(data, datalen, hashRslt, &hashLen, EVP_sm3(), NULL, sign_key)) {
// debug("EVP_Digest ERROR \n");
// return 1;
// }
最新的代码
static int
ukey_get_sig(u_char *data, size_t datalen, u_char **sig, size_t *slen, struct sshkey *sign_key)
{
// get container handle
ULONG ulRslt = SAR_OK;
HCONTAINER container = NULL;
DEVHANDLE hDev = NULL;
if (init_ukey_container(&container, &hDev) != 0) {
debug("init_ukey_container ERROR \n");
return 1;
}
BYTE buf[132] = {0};
ULONG bufLen = sizeof(buf);
ulRslt = SKF_ExportPublicKey(container, TRUE, buf, &bufLen);
if (ulRslt != SAR_OK) {
debug("SKF_ExportPublicKey ERROR \n");
return 1;
}
// hash
unsigned char hashRslt[32] = {0};
int hashLen;
ECCPUBLICKEYBLOB *blob = (ECCPUBLICKEYBLOB *)buf;
const unsigned char *sm2_id = (const unsigned char *)"1234567812345678";
HANDLE phHash = NULL;
ulRslt = SKF_DigestInit(hDev, SGD_SM3, blob, sm2_id, 16, &phHash);
if (ulRslt != SAR_OK) {
debug("ulRsltSKF_DigestInit:%d", ulRslt);
}
ulRslt = SKF_Digest(phHash, data, datalen, hashRslt, &hashLen);
if (ulRslt != SAR_OK) {
debug("SKF_Digest:%d", ulRslt);
}
// if(1 != EVP_Digest(data, datalen, hashRslt, &hashLen, EVP_sm3(), NULL, sign_key)) {
// debug("EVP_Digest ERROR \n");
// return 1;
// }
// sign
ECCSIGNATUREBLOB stSign = {0};
ulRslt = SKF_ECCSignData(container, hashRslt, hashLen, &stSign);
if (ulRslt != SAR_OK) {
debug("SKF_ECCSignData ERROR \n");
return 1;
}
SM2_gmSig2OpensslSig(&stSign, sig, slen);
return 0;
}
使用update和final
static int
ukey_get_sig(u_char *data, size_t datalen, u_char **sig, size_t *slen, struct sshkey *sign_key)
{
// get container handle
ULONG ulRslt = SAR_OK;
HCONTAINER container = NULL;
DEVHANDLE hDev = NULL;
if (init_ukey_container(&container, &hDev) != 0) {
debug("init_ukey_container ERROR \n");
return 1;
}
BYTE buf[132] = {0};
ULONG bufLen = sizeof(buf);
ulRslt = SKF_ExportPublicKey(container, TRUE, buf, &bufLen);
if (ulRslt != SAR_OK) {
debug("SKF_ExportPublicKey ERROR \n");
return 1;
}
// hash
unsigned char hashRslt[32] = {0};
int hashLen;
ECCPUBLICKEYBLOB *blob = (ECCPUBLICKEYBLOB *)buf;
const unsigned char *sm2_id = (const unsigned char *)"1234567812345678";
HANDLE phHash = NULL;
ulRslt = SKF_DigestInit(hDev, SGD_SM3, blob, sm2_id, 16, &phHash);
if (ulRslt != SAR_OK) {
debug("ulRsltSKF_DigestInit:%d", ulRslt);
}
ulRslt = SKF_DigestUpdate(phHash, data, datalen);
if (ulRslt != SAR_OK) {
debug("SKF_Digest:%d", ulRslt);
}
ulRslt = SKF_DigestFinal(phHash, hashRslt, &hashLen);
if (ulRslt != SAR_OK) {
debug("SKF_DigestFinal:%d", ulRslt);
}
// hash with EVP_Digest(openssl)
// if(1 != EVP_Digest(data, datalen, hashRslt, &hashLen, EVP_sm3(), NULL, sign_key)) {
// debug("EVP_Digest ERROR \n");
// return 1;
// }
// sign
ECCSIGNATUREBLOB stSign = {0};
ulRslt = SKF_ECCSignData(container, hashRslt, hashLen, &stSign);
if (ulRslt != SAR_OK) {
debug("SKF_ECCSignData ERROR \n");
return 1;
}
SM2_gmSig2OpensslSig(&stSign, sig, slen);
return 0;
}
最新的:
static int
ukey_get_sig(u_char *data, size_t datalen, u_char **sig, size_t *slen, struct sshkey *sign_key)
{
// get container handle
ULONG ulRslt = SAR_OK;
HCONTAINER container = NULL;
DEVHANDLE hDev = NULL;
if (init_ukey_container(&container, &hDev) != 0) {
debug("init_ukey_container ERROR \n");
return 1;
}
BYTE buf[132] = {0};
ULONG bufLen = sizeof(buf);
ulRslt = SKF_ExportPublicKey(container, TRUE, buf, &bufLen);
if (ulRslt != SAR_OK) {
debug("SKF_ExportPublicKey ERROR \n");
return 1;
}
// hash
unsigned char hashRslt[32] = {0};
int hashLen = 32;
// unsigned char *hashRslt = NULL;
ECCPUBLICKEYBLOB *blob = (ECCPUBLICKEYBLOB *)buf;
const unsigned char *sm2_id = (const unsigned char *)"1234567812345678";
HANDLE phHash = NULL;
ulRslt = SKF_DigestInit(hDev, SGD_SM3, sm2_id, 16, 0, &phHash);
if (ulRslt != SAR_OK) {
debug("ulRsltSKF_DigestInit:%d", ulRslt);
}
ulRslt = SKF_Digest(phHash, data, 256, hashRslt, &hashLen);
if (ulRslt != SAR_OK) {
debug("SKF_Digest:%d", ulRslt);
}
// sign
ECCSIGNATUREBLOB stSign = {0};
ulRslt = SKF_ECCSignData(container, hashRslt, hashLen, &stSign);
if (ulRslt != SAR_OK) {
debug("SKF_ECCSignData ERROR \n");
return 1;
}
SM2_gmSig2OpensslSig(&stSign, sig, slen);
return 0;
}
2024-04-19 已经能够通过公钥测试,并在客户端成功对签名信息做哈希,并签名,然后发送。现在问题在服务端接受到签名信息后表示不允许这个公钥。
客户端准备
客户端的公钥硬编码在代码中,使用我的ukey就不需要修改 ukey的初始密码是
12345678
代码仓为:20240408_yuyebin_userauth_with_ukey新增配置(直接放在/etc/ssh/ssh_config中也行)
公钥
服务端准备
修改配置文件
修改保存公钥的文件,地址在上面的config中
AuthorizedKeysFile /authorized_keys
现状
sshd在这里报错: