HUKS Access Control Development
For details about scenarios and related concepts, see HUKS Access Control Overview.
How to Develop
-
Generate a key, enable fingerprint authentication for key access, and set related parameters. When a key is generated or imported, set HuksUserAuthType, HuksAuthAccessType, and HuksChallengeType.
import huks from '@ohos.security.huks'; import { BusinessError } from '@ohos.base'; /* * Set the key alias and encapsulate the key property set. */ let keyAlias = 'test_sm4_key_alias'; let properties: Array<huks.HuksParam> = new Array(); properties[0] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_SM4, } properties[1] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, } properties[2] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, } properties[3] = { tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, value: huks.HuksCipherMode.HUKS_MODE_CBC, } properties[4] = { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_NONE, } // Set HuksUserAuthType to fingerprint authentication. properties[5] = { tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT } // Set HuksAuthAccessType to HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL, which invalidates the key when a new biometric feature (fingerprint) is enrolled. properties[6] = { tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL } // Use the default challenge type. properties[7] = { tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL } let huksOptions : huks.HuksOptions = { properties: properties, inData: new Uint8Array(new Array()) } /* * Generate a key. */ class throwObject { isThrow:boolean = false } function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { return new Promise<void>((resolve, reject) => { try { huks.generateKeyItem(keyAlias, huksOptions, (error, data) => { if (error) { reject(error); } else { resolve(data); } }); } catch (error) { throwObject.isThrow = true; throw(error as Error); } }); } async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { console.info(`enter promise generateKeyItem`); let throwObject : throwObject = {isThrow: false}; try { await generateKeyItem(keyAlias, huksOptions, throwObject) .then((data) => { console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`); }) .catch((error : BusinessError) => { if (throwObject.isThrow) { throw(error as Error); } else { console.error(`promise: generateKeyItem failed` + error); } }); } catch (error) { console.error(`promise: generateKeyItem input arg invalid` + error); } } async function TestGenKeyForFingerprintAccessControl() { await publicGenKeyFunc(keyAlias, huksOptions); }
-
Initialize a key session to initiate fingerprint authentication. If the authentication is successful, an authentication token (AuthToken) is returned.
import huks from '@ohos.security.huks'; import userIAM_userAuth from '@ohos.userIAM.userAuth'; import { BusinessError } from '@ohos.base'; /* * Set the key alias and encapsulate the key property set. */ let srcKeyAlias = 'test_sm4_key_alias'; let handle : number; let challenge : Uint8Array; let fingerAuthToken : Uint8Array; let authType = userIAM_userAuth.UserAuthType.FINGERPRINT; let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1; /* Set the key generation parameter set and key encryption parameter set. */ let properties : Array<huks.HuksParam> = new Array(); properties[0] = { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_SM4, } properties[1] = { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, } properties[2] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, } properties[3] = { tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, value: huks.HuksCipherMode.HUKS_MODE_CBC, } properties[4] = { tag: huks.HuksTag.HUKS_TAG_PADDING, value: huks.HuksKeyPadding.HUKS_PADDING_NONE, } properties[5] = { tag: huks.HuksTag.HUKS_TAG_IV, value: StringToUint8Arry(IV), } let huksOptions : huks.HuksOptions = { properties: properties, inData: new Uint8Array(new Array()) } class throwObject { isThrow:boolean=false } function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) { return new Promise<huks.HuksSessionHandle>((resolve, reject) => { try { huks.initSession(keyAlias, huksOptions, (error, data) =>{ if (error) { reject(error); } else { resolve(data); } }); } catch (error) { throwObject.isThrow = true; throw(error as Error); } }); } async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { console.info(`enter promise doInit`); let throwObject : throwObject = {isThrow: false}; try { await initSession(keyAlias, huksOptions, throwObject) .then ((data) => { console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); handle = data.handle; challenge = data.challenge as Uint8Array; }) .catch((error : BusinessError) => { if (throwObject.isThrow) { throw(error as Error); } else { console.error(`promise: doInit failed` + error); } }); } catch (error) { console.error(`promise: doInit input arg invalid` + error); } } function userIAMAuthFinger(huksChallenge:Uint8Array) { // Obtain an authentication object. let authTypeList:userIAM_userAuth.UserAuthType[]= new Array(); authTypeList[0] = authType; const authParam:userIAM_userAuth.AuthParam = { challenge: huksChallenge, authType: authTypeList, authTrustLevel: userIAM_userAuth.AuthTrustLevel.ATL1 }; const widgetParam:userIAM_userAuth.WidgetParam = { title: 'Enter password', }; let auth : userIAM_userAuth.UserAuthInstance; try { auth = userIAM_userAuth.getUserAuthInstance(authParam, widgetParam); console.log("get auth instance success"); } catch (error) { console.error("get auth instance failed" + error); return; } // Subscribe to the authentication result. try { auth.on("result", { onResult(result) { console.log("[HUKS] -> [IAM] userAuthInstance callback result = " + JSON.stringify(result)); fingerAuthToken = result.token; } }); console.log("subscribe authentication event success"); } catch (error) { console.error("subscribe authentication event failed " + error); } // Start user authentication. try { auth.start(); console.info("authV9 start auth success"); } catch (error) { console.error("authV9 start auth failed, error = " + error); } } async function testInitAndAuthFinger() { /* Initialize the key session to obtain a challenge. */ await publicInitFunc(srcKeyAlias, huksOptions); /* Invoke userIAM to perform user identity authentication. */ userIAMAuthFinger(challenge); }
-
Pass in AuthToken to perform data operations.
/* * The following uses a 128-bit SM4 key as an example. */ import huks from '@ohos.security.huks'; import { BusinessError } from '@ohos.base'; /* * Determine the key property set to be encapsulated. */ let IV = '1234567890123456'; let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; let handle: number; let fingerAuthToken: Uint8Array; let finishOutData: Uint8Array; class throwObject { isThrow: boolean = false; } /* Set the key generation parameter set and key encryption parameter set. */ class propertyEncryptType { tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM; value: huks.HuksKeyAlg | huks.HuksKeyPurpose | huks.HuksKeySize | huks.HuksKeyPadding | huks.HuksCipherMode
| Uint8Array = huks.HuksKeyAlg.HUKS_ALG_SM4;
}
let propertiesEncrypt: propertyEncryptType[] = [
{
tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
value: huks.HuksKeyAlg.HUKS_ALG_SM4,
},
{
tag: huks.HuksTag.HUKS_TAG_PURPOSE,
value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT,
},
{
tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
},
{
tag: huks.HuksTag.HUKS_TAG_PADDING,
value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
},
{
tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
value: huks.HuksCipherMode.HUKS_MODE_CBC,
},
{
tag: huks.HuksTag.HUKS_TAG_IV,
value: StringToUint8Array(IV),
}
]
let encryptOptions: huks.HuksOptions = {
properties: propertiesEncrypt,
inData: new Uint8Array(new Array())
}
function StringToUint8Array(str: string) {
let arr: number[] = [];
for (let i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
return new Uint8Array(arr);
}
function updateSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) {
return new Promise<huks.HuksReturnResult>((resolve, reject) => {
try {
huks.updateSession(handle, huksOptions, token, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
} catch (error) {
throwObject.isThrow = true;
throw(error as Error);
}
});
}
async function publicUpdateFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) {
console.info(enter promise doUpdate
);
let throwObject: throwObject = {isThrow: false};
try {
await updateSession(handle, huksOptions, token, throwObject)
.then ((data) => {
console.info(promise: doUpdate success, data = ${JSON.stringify(data)}
);
})
.catch((error: BusinessError) => {
if (throwObject.isThrow) {
throw(error as Error);
} else {
console.error(promise: doUpdate failed
+ error);
}
});
} catch (error) {
console.error(promise: doUpdate input arg invalid
+ error);
}
}
function finishSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) {
return new Promise<huks.HuksReturnResult>((resolve, reject) => {
try {
huks.finishSession(handle, huksOptions, token, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
} catch (error) {
throwObject.isThrow = true;
throw(error as Error);
}
});
}
async function publicFinishFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) {
console.info(enter promise doFinish
);
let throwObject: throwObject = {isThrow: false};
try {
await finishSession(handle, huksOptions, token, throwObject)
.then ((data) => {
finishOutData = data.outData as Uint8Array;
console.info(promise: doFinish success, data = ${JSON.stringify(data)}
);
})
.catch((error: BusinessError) => {
if (throwObject.isThrow) {
throw(error as Error);
} else {
console.error(promise: doFinish failed
+ error);
}
});
} catch (error) {
console.error(promise: doFinish input arg invalid
+ error);
}
}
async function testSm4Cipher() {
encryptOptions.inData = StringToUint8Array(cipherInData);
/* Pass in AuthToken. /
await publicUpdateFunc(handle, fingerAuthToken, encryptOptions);
/ Pass in AuthToken. */
await publicFinishFunc(handle, fingerAuthToken, encryptOptions);
if (finishOutData === StringToUint8Array(cipherInData)) {
console.info('test finish encrypt err ');
} else {
console.info('test finish encrypt success');
}
}