NSS Sample Code sample6 编辑
NSS Sample Code 6: Persistent Symmetric Keys in NSS database
/* Example code to illustrate generation of a secret symmetric key ring * that PERSISTS in the NSS database. The symmetric keys can then be used * without ever exposing them in the clear. * * To encrypt, you need the id of the key to use. * To decrypt, you need the ciphertext and the id of the key that was used * to encrypt * * Before running this example, create the NSS database * certutil -N -d . * (enter "test" when prompted for password) */ #include "nss.h" #include "pk11pub.h" /* the key id can be any sequence of bytes. this example happens to use an * integer */ void genkey(int id); /* this callback is responsible for returning the password to the NSS * key database. for example purposes, this function hardcodes the password. * In a real app, this function should obtain the password using secure means * such as prompting an operator, or retrieving it over a secure communication * channel */ char *passwdcb(PK11SlotInfo *info, PRBool retry, void *arg); int main(int argc, char **argv) { SECStatus rv; /* Initialize NSS */ PK11_SetPasswordFunc(passwdcb); /* The NSS db must be initialized read-write since we'll be creating * keys in it. Once keys are generated, it can be opened without read-write * subsequently (NSS_Init). */ rv = NSS_InitReadWrite("."); if (rv != SECSuccess) { fprintf(stderr, "NSS initialization failed (err %d)\n", PR_GetError()); exit(1); } /* generate a key with id 1. should succeed on first run on a fresh db, * should fail on successive runs because key with that id already exists */ genkey(1); /* generate a key with id 2. should succeed on first run on a fresh db, * should fail on successive runs because key with that id already exists */ genkey(2); /* generate a key with id 1 - this will fail because key with that id * already exists */ genkey(1); } void genkey(int id) { PK11SlotInfo* slot = NULL; PK11SymKey* key = NULL; SECItem keyiditem; int keyid[1]; CK_MECHANISM_TYPE cipherMech; /* using CKM_AES_CBC_PAD mechanism for example */ cipherMech = CKM_AES_CBC_PAD; slot = PK11_GetInternalKeySlot(); /* slot = PK11_GetBestSlot(cipherMech, NULL); didn't work. * Error code: token is read-only. ?? */ if (slot == NULL) { fprintf(stderr, "Unable to find security device (err %d)\n", PR_GetError()); return; } keyid[0] = id; keyiditem.type = siBuffer; keyiditem.data = (void *)keyid; keyiditem.len = sizeof(keyid[0]); /* Note: keysize must be 0 for fixed key-length algorithms like DES. * Since we're using AES in this example, we're specifying * one of the valid keysizes (16, 24, 32) */ key = PK11_TokenKeyGen(slot, cipherMech, 0, 32 /*keysize*/, &keyiditem, PR_TRUE, 0); if (key == NULL) { fprintf(stderr, "PK11_TokenKeyGen failed (err %d)\n", PR_GetError()); PK11_FreeSlot(slot); return; } fprintf(stderr, "key length of generated key is %d\n", PK11_GetKeyLength(key)); fprintf(stderr, "mechanism of key is %d (asked for %d)\n", PK11_GetMechanism(key), cipherMech); PK11_FreeSymKey(key); key = PK11_FindFixedKey(slot, cipherMech, &keyiditem, 0); if (key == NULL) { fprintf(stderr, "PK11_FindFixedKey failed (err %d)\n", PR_GetError()); PK11_FreeSlot(slot); return; } fprintf(stderr, "Found key!\n"); fprintf(stderr, "key length of generated key is %d\n", PK11_GetKeyLength(key)); fprintf(stderr, "mechanism of key is %d (asked for %d)\n", PK11_GetMechanism(key), cipherMech); PK11_FreeSymKey(key); PK11_FreeSlot(slot); } char *passwdcb(PK11SlotInfo *info, PRBool retry, void *arg) { if (!retry) return PL_strdup("test"); else return NULL; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论