测试已测试 | ✓ |
语言语言 | Objective C++Objective C++ |
许可证 | BSD |
发布最后发布 | 2018年1月 |
由 SanjoDeundiak,Sergey Seroshtan 维护。
这是一个基本的底层框架,允许执行一些最重要的安全操作。此框架被用于其他高级 Virgil 框架、库和应用程序中。它也可以作为任何关注安全的独立基本库。
如果您打算使用任何高级 Virgil 框架,例如 VirgilSDK,那么您不需要直接安装 VirgilFoundation。它将随高级框架的所有必需依赖项一起安装。
本章的其余部分描述了如何直接安装 VirgilFoundation 框架。使用 CocoaPods 安装和维护 VirgilFoundation 框架是针对 Objective-C/Swift 应用程序的最简单和推荐方式。
$ sudo gem install cocoapods
CocoaPods 是用 Ruby 构建的,并且可以通过 OS X 上默认的 Ruby 安装。
$ cd <Path to Xcode project folder>
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target '<Put your Xcode target name here>' do
pod 'VirgilFoundation'
end
$ pod install
到此为止,您应该能够在代码中使用 Virgil 密码功能。下面列出了最常见任务的一些示例。如果您在 CocoaPods 安装过程中遇到任何问题,请尝试在 cocoapods.org 找到更多信息。
尽管VirgilFoundation使用Objective-C作为其主要语言,但在Swift应用程序中使用它却非常简单。按照入门部分描述安装VirgilFoundation后,需要执行以下操作。
@import VirgilFoundation;
您可以在此处找到有关在同一个项目中使用Objective-C和Swift的更多信息。
以下您可以找到使用VirgilFoundation框架能够执行的大部分常见任务的示例。
应该使用VSSKeyPair实例来生成一对密钥。可以生成一个受密码保护的私钥。如果没有提供密码,私钥将以纯数据形式生成。
//...
VSSKeyPair *keyPair = [[VSSKeyPair alloc] initWithPassword:<#Password or nil#>];
NSString *publicKey = [[NSString alloc] initWithData:keyPair.publicKey encoding:NSUTF8StringEncoding];
NSLog(@"%@", publicKey);
NSString *privateKey = [[NSString alloc] initWithData:keyPair.privateKey encoding:NSUTF8StringEncoding];
NSLog(@"%@", privateKey);
//...
//...
let keyPair = VSSKeyPair(password:<#Password or nil#>)
println(NSString(data: keyPair.publicKey(), encoding: NSUTF8StringEncoding))
println(NSString(data: keyPair.privateKey(), encoding: NSUTF8StringEncoding))
//...
VSSCryptor对象可以执行两种加密/解密方式
//...
// Assuming that we have some initial string message.
NSString *message = @"This is a secret message which should be encrypted.";
// Convert it to the NSData
NSData *toEncrypt = [message dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
VSSCryptor *cryptor = [[VSSCryptor alloc] init];
// Now we should add a key recipient
NSError *error = nil;
if (![cryptor addKeyRecipient:<# Recipient ID #> publicKey:<# keyPair.publicKey #> error:&error]) {
NSLog(@"Error adding key recipient: %@", [error localizedDescription]);
return;
}
// And now we can easily encrypt the plain data
NSData *encryptedData = [cryptor encryptData:toEncrypt embedContentInfo:YES error:&error];
if (error != nil) {
NSLog(@"Error encrypting data: %@", [error localizedDescription]);
return;
}
//...
//...
// Assuming that we have some initial string message.
let message = NSString(string: "This is a secret message which should be encrypted.")
// Convert it to the NSData
if let toEncrypt = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
let cryptor = VSSCryptor()
// Now we should add a key recipient
var encryptedData = NSData()
do {
try cryptor.addKeyRecipient(<# Recipient ID #>, publicKey: <# keyPair.publicKey() #>, error: ())
// And now we can easily encrypt the plain data
encryptedData = try cryptor.encryptData(toEncrypt, embedContentInfo: true, error: ())
}
catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
//...
}
//...
//...
// Assuming that we have received some key-based encrypted data.
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
VSSCryptor *decryptor = [[VSSCryptor alloc] init];
// Decrypt data
NSError *error = nil;
NSData *plainData = [decryptor decryptData:<# NSData containing encrypted data #> recipientId:<# Recipient ID #> privateKey:<# keyPair.privateKey #> keyPassword:<# Private key password or nil #> error:&error];
if (error != nil) {
NSLog(@"Error decrypting data: %@", [error localizedDescription]);
return;
}
// Compose initial message from the plain decrypted data
NSString *initialMessage = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
//...
//...
// Assuming that we have received some key-based encrypted data.
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
let decryptor = VSSCryptor()
// Decrypt data
do {
let plainData = try decryptor.decryptData(<# NSData with encrypted data #>, recipientId: <# Recipient ID #>, privateKey: <# keyPair.privateKey() #>, keyPassword: <# Private key password or nil #>, error: ())
// Compose initial message from the plain decrypted data
if let initialMessage = NSString(data: plainData, encoding: NSUTF8StringEncoding) {
// Use initialMessage.
//...
}
}
catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
//...
//...
// Assuming that we have some initial string message.
NSString *message = @"This is a secret message which should be encrypted with password-based encryption.";
// Convert it to the NSData
NSData *toEncrypt = [message dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
VSSCryptor *cryptor = [[VSSCryptor alloc] init];
NSError *error = nil;
if (![cryptor addPasswordRecipient:<# Password to encrypt data with #> error:&error]) {
NSLog(@"Error adding password recipient: %@", [error localizedDescription]);
return;
}
// And now we can encrypt the plain data
NSData *encryptedData = [cryptor encryptData:toEncrypt embedContentInfo:YES error:&error];
if (error != nil) {
NSLog(@"Error encrypting data: %@", [error localizedDescription]);
return;
}
//...
//...
// Assuming that we have some initial string message.
let message = NSString(string: "This is a secret message which should be encrypted.")
// Convert it to the NSData
if let toEncrypt = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
// Create a cryptor instance
var encryptedData = NSData()
let cryptor = VSSCryptor()
do {
try cryptor.addPasswordRecipient(<# Password to encrypt data with #>, error: ())
encryptedData = try cryptor.encryptData(toEncrypt, embedContentInfo: true, error: ())
}
catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
}
//...
//...
// Assuming that we have received some password-based encrypted data.
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
VSSCryptor *decryptor = [[VSSCryptor alloc] init];
// Decrypt data
NSError *error = nil;
NSData *plainData = [decryptor decryptData:<# NSData with encrypted data #> password:<# Password used for encryption #> error:&error];
if (error != nil) {
NSLog(@"Error decrypting data: %@", [error localizedDescription]);
return;
}
// Compose initial message from the plain decrypted data
NSString *initialMessage = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
//...
//...
// Assuming that we have received some password-based encrypted data.
// Assuming that we have some key pair generated earlier.
// Create a new VSSCryptor instance
let decryptor = VSSCryptor()
// Decrypt data
do {
let plainData = try decryptor.decryptData(NSData(), password: "", error: ())
// Compose initial message from the plain decrypted data
if let initialMessage = NSString(data: plainData, encoding: NSUTF8StringEncoding) {
// Use initialMessage.
//...
}
}
catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
//...
VSSSigner实例允许使用给定的私钥对某些数据进行签名。这可以用来确保某些消息/数据确实是由私钥的持有者生成并发送的。
//...
// Assuming that we have some initial string message that we want to sign.
NSString *message = @"This is a secret message which should be signed.";
// Convert it to the NSData
NSData *toSign = [message dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
// Assuming that we have some key pair generated earlier.
// Create a new VSSSigner instance
VSSSigner *signer = [[VSSSigner alloc] init];
// Sign the initial data
NSError *error = nil;
NSData *signature = [signer signData:toSign privateKey:<# keyPair.privateKey #> keyPassword:<# Private key password or nil #> error:&error];
if (error != nil) {
NSLog(@"Error composing a signature: %@", [error localizedDescription]);
return;
}
// Use the signature.
//...
//...
// Assuming that we have some initial string message.
let message = NSString(string: "This is a secret message which should be signed.")
// Convert it to the NSData
if let toSign = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
// Create the signer
let signer = VSSSigner()
// Compose the signature
do {
let signature = try signer.signData(toSign, privateKey: <# keyPair.privateKey() #>, keyPassword: <# Private key password or nil #>, error: ())
// Use the signature.
//...
}
catch let error as NSError {
print("Error composing a signature: \(error.localizedDescription)")
}
}
//...
要验证某些签名,需要拥有我们想要验证签名的用户的公钥。
//...
// Assuming that we have the public key of a person whose signature we need to verify
// Assuming that we have a NSData object with signed data.
// Assuming that we have a NSData object with a signature.
// Create a new VSSSigner instance
VSSSigner *verifier = [[VSSSigner alloc] init];
// Verify the signature.
NSError *error = nil;
if (![verifier verifySignature:<# NSData containing the signature #> data:<# NSData used to compose the signature #> publicKey:<# keyPair.publicKey #> error:&error]) {
NSLog(@"Error signature verification: %@", [error localizedDescription]);
return;
}
// Signature seems OK.
//...
//...
// Assuming that we have the public key of a person whose signature we need to verify
// Assuming that we have a NSData object with signed data.
// Assuming that we have a NSData object with a signature.
// Create a new VSSSigner instance
let verifier = VSSSigner()
// Verify the signature.
do {
try verifier.verifySignature(<# NSData containing the signature #>, data: <# NSData used to compose the signature #>, publicKey: <# keyPair.publicKey() #>, error: ())
// Signature seems OK.
//...
}
catch let error as NSError {
print("Error signature verification: \(error.localizedDescription)")
}
//...
这项功能允许基于给定的初始参数生成字节序列,以确保相同的参数产生相同的字节序列。当应用程序不希望以明文形式使用某些敏感数据时(例如在会话之间保存密码或操作其他用户数据,例如电子邮件、电话号码等),这可能会很有用。在这种情况下,应用程序可以基于密码、电子邮件地址或其他任何明文数据生成安全的序列,这样这些数据将不会被泄露。使用生成的字节序列恢复初始明文数据是不可能的(或者至少在合理的时间内是不可能的)。以下是一些示例。
//...
// Assuming that we have some password which the application does not to expose in plain form.
NSString *password = <# NSString: user password in plain form#>;
// Create a new VSSPBKDF instance
// Salt parameter should contain the random sequence of bytes. In general, salt is public information.
// If salt parameter is nil then VSSPBKDF will generate random salt automatically.
// If it is necessary to generate the same data later based on the user's input of the password
// it is recommended to generate salt data and store it for further use in VSSPBKDF instance creations:
NSData *salt = [VSSPBKDF randomBytesOfSize:<#size_t: size of the salt in bytes or 0 #>];
// Iterations parameter should contain number of iterations for derivation function.
// If iterations == 0 then VSSPBKDF will use default number of iterations.
VSSPBKDF *pbkdf = [[VSSPBKDF alloc] initWithSalt:<#NSData: salt or nil for default new salt generation#> iterations:<#unsigned int: iterations count or 0 for default count #>];
NSError *error = nil;
// Derive secure sequence of bytes with required size based on the plain password.
NSData *data = [pbkdf keyFromPassword:password size:<# size_t: Desired length in bytes of the output data sequence #> error:&error];
if (error != nil) {
NSLog(@"Error: %@", [error localizedDescription]);
return;
}
// Use the data instead of plain password.
//...
//...
// Assuming that we have some password which the application does not to expose in plain form.
let password = <# String: user password in plain form#>;
// Create a new VSSPBKDF instance
// Salt parameter should contain the random sequence of bytes. In general, salt is public information.
// If salt parameter is nil then VSSPBKDF will generate random salt automatically.
// If it is necessary to generate the same data later based on the user's input of the password
// it is recommended to generate salt data and store it for further use in VSSPBKDF instance creations:
let salt = VSSPBKDF.randomBytesOfSize(<#size_t: size of the salt in bytes or 0 #>)
// Iterations parameter should contain number of iterations for derivation function.
// If iterations == 0 then VSSPBKDF will use default number of iterations.
let pbkdf = VSSPBKDF(salt:<# NSData: salt or nil for default new salt generation #>, iterations: <#unsigned int: iterations count or 0 for default count #>)
do {
// Derive secure sequence of bytes with required size based on the plain password.
let data = try pbkdf.keyFromPassword(password, size: <# size_t: Desired length in bytes of the output data sequence #>)
// Use the data instead of plain password.
}
catch (let error as NSError) {
print("Error: \(error.localizedDescription)")
return
}
//...
使用受BSD 3-Clause License协议规范。有关详细内容,请参阅LICENSE文件。