序列號形如 :
1330-1440-1602-3671-9749-7897
XDM3T-W3T3V-MGJWK-8BFVD-GVPKY技術實現:受權序列號,是通過私鑰加密的受權信息的字符串,設備中使用公鑰解密,獲得正確受權信息,則設備被激活. RSA非對稱加密算法限制:受權信息須要儘可能短,由於rsa 加密算法庫(openssl)可加密長度有限制(與私鑰長度有關,未具體瞭解),因此要用盡可能少的數據保存儘可能長的受權信息.
受權文件中的內容形如:
{"ver": 1,"info": {"productid": "vW2TNOMlLvZdAgAF","invaliddate": "2014-05-16 11:40:30","userlimit": 100},"signature": [25, 218, 203, 190, 99, 76, 192, 136, 176, 181, 198, 128, 14, 250, 189, 198, 152, 208, 15, 202, 233, 77, 189, 3, 44, 113, 65, 231, 51, 100, 208, 127, 19, 255, 139, 174, 62, 9, 76, 165, 137, 15, 165, 178, 138, 9, 32, 218, 209, 222, 6, 234, 94, 5, 41, 130, 27, 232, 37, 195, 52, 120, 81, 143, 103, 40, 90, 93, 240, 115, 5, 117, 230, 65, 243, 182, 141, 64, 179, 140, 137, 155, 219, 75, 87, 83, 36, 49, 178, 210, 53, 171, 254, 28, 88, 39, 241, 57, 68, 204, 46, 231, 180, 133, 134, 108, 114, 243, 163, 30, 201, 103, 138, 15, 23, 247, 54, 32, 64, 181, 71, 12, 14, 88, 247, 156, 138, 32]}技術實現:受權文件包含明文的"受權信息"以及使用私鑰進行的"受權信息的 簽名"組成的字符串.設備使用公鑰進行簽名的驗證.(相對於序列號的幾十個字符串來講,這裏的字符串確定會超過幾百個,因此保存在文件中方便用戶輸入設備).
技術實現:須要有一臺公網服務器,處理查詢受權信息的請求.用戶不須要輸入任何序列號,只須要點擊一個"更新"按鈕,設備主動發送自身的硬件惟一ID,向某一服務器請求受權信息(獲得第2種方案中的受權文件),成功獲取到後,設備會自動激活.
openssl genrsa -out private.pem 2048
|
openssl rsa -in private.pem -pubout -out public.pem
|
int readpub_rsakey(const char *filename, RSA **prsa)
{
FILE *fp = fopen(filename, "r");
if (NULL == fp) {
printf("fopen() fail!\n");
return -1;
}
*prsa =
PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
if (NULL == *prsa) {
printf("read_rsa_pubkey() fail!\n");
fclose(fp);
return -1;
}
fclose(fp);
return 0;
}
int readpri_rsakey(const char *filename, RSA **prsa)
{
FILE *fp = fopen(filename, "r");
if (NULL == fp) {
printf("fopen fail!\n");
return -1;
}
*prsa =
PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
if (NULL == *prsa) {
printf("read_rsa_prikey() fail!\n");
fclose(fp);
return -1;
}
fclose(fp);
return 0;
}
|
int getpub_rsakey(const char *key, RSA **prsa)
{
BIO *bio = NULL;
if (NULL == (bio = BIO_new_mem_buf((void*)key, -1))) {
printf("BIO_new_membuf() fail!\n");
return -1;
}
*prsa =
PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
if (!(*prsa)) {
printf("PEM_readbio_RSA_PUBKEY() fali!\n");
BIO_free_all(bio);
return -1;
}
return 0;
}
int getpri_rsakey(const char *key, RSA **prsa)
{
BIO *bio = NULL;
if (NULL == (bio = BIO_new_mem_buf((void*)key, -1))) {
printf("BIO_new_membuf() fail!\n");
return -1;
}
*prsa =
PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
if (!(*prsa)) {
printf("PEM_read_bio_RSAPrivateKey() fail!\n");
BIO_free_all(bio);
return -1;
}
return 0;
}
|
int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
|