Сохраните строку в хранилище ключей iOS из Nativescript - PullRequest
0 голосов
/ 10 сентября 2018

Я пишу плагин Nativescript, который выполняет вызовы к Android / Java Cipher и другим криптографическим классам. Мне нужно сохранить строку в цепочке для ключей, которая может быть сохранена / прочитана, только если пользователь прошел аутентификацию через TouchId или FaceId, и у меня работает TouchId / FaceId, но у меня возникают проблемы с выяснением, как хранить и читать строку.

У меня есть следующий код, который хранит строку, и это возможно работает (я не знаю, пока не попробую прочитать ее снова):

private createKeyChainEntry(data: string): boolean {
let attributes;
try {
  attributes = NSMutableDictionary.new();
  attributes.setObjectForKey(kSecClassGenericPassword, kSecClass);
  attributes.setObjectForKey(keychainItemIdentifier, kSecAttrAccount);
  attributes.setObjectForKey(this.keychainItemServiceName, kSecAttrService);
} catch (ex) {
  console.trace(ex);
}
const accessControlRef = SecAccessControlCreateWithFlags(
  kCFAllocatorDefault,
  kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
  SecAccessControlCreateFlags.kSecAccessControlUserPresence,
  null
);
if (accessControlRef === null) {
  // console.log(`Can't store identifier '${keychainItemIdentifier}' in the KeyChain: ${accessControlError}.`);
  console.log(`Can't store identifier '${keychainItemIdentifier}' in the KeyChain.`);
  return false;
} else {
  attributes.setObjectForKey(accessControlRef, kSecAttrAccessControl);
  // The content of the password is not important
  const content = NSString.stringWithString(data);
  const nsData = content.dataUsingEncoding(NSUTF8StringEncoding);
  attributes.setObjectForKey(nsData, kSecValueData);
  SecItemAdd(attributes, null);
  return true;
}
}

У меня также есть этот код, где я пытаюсь снова прочитать строку, но я не знаю, как получить фактическую строку из privKeyRef / resultData:

private readKeyChainEntry(): string {
let attributes;
try {
  attributes = NSMutableDictionary.new();
  attributes.setObjectForKey(kSecClassGenericPassword, kSecClass);
  attributes.setObjectForKey(keychainItemIdentifier, kSecAttrAccount);
  attributes.setObjectForKey(this.keychainItemServiceName, kSecAttrService);
  attributes.setObjectForKey(true, kSecReturnData);
} catch (ex) {
  console.trace(ex);
}
const accessControlRef = SecAccessControlCreateWithFlags(
  kCFAllocatorDefault,
  kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
  SecAccessControlCreateFlags.kSecAccessControlUserPresence,
  null
);
console.log("readKeyChainEntry #3");
if (accessControlRef === null) {
  // console.log(`Can't store identifier '${keychainItemIdentifier}' in the KeyChain: ${accessControlError}.`);
  console.log(`Can't store identifier '${keychainItemIdentifier}' in the KeyChain.`);
  return null;
} else {
  console.log("readKeyChainEntry #4");
  attributes.setObjectForKey(accessControlRef, kSecAttrAccessControl);
  console.log("readKeyChainEntry #5");
  const privKeyRef = new interop.Reference<any>();
  let resultData: NSData;
  let status = SecItemCopyMatching(attributes, privKeyRef);
  console.log("readKeyChainEntry #6: " + status);
  if (status == errSecSuccess) {
    resultData = privKeyRef.value;
    console.log("resultData: " + resultData);
    console.log(NSString.new().initWithDataEncoding(resultData, NSUTF8StringEncoding));
  }
}
return null;
}
...