Welcome to the .NET SDK Programming Guide for C#. This guide is a practical introduction to creating apps for the Windows/Xamarin platform that make use of Virgil Security features. The code examples in this guide are written in C#.
In this guide you will find code for every task you need to implement in order to create an application using Virgil Security. It also includes a description of the main classes and methods. The aim of this guide is to get you up and running quickly. You should be able to copy and paste the code provided into your own apps and use it with minumal changes.
- Setting up your project
- User and App Credentials
- Creating a Virgil Card
- Search for Virgil Cards
- Getting a Virgil Card
- Validating Virgil Cards
- Revoking a Virgil Card
- Operations with Crypto Keys
- Encryption and Decryption
- Generating and Verifying Signatures
- Authenticated Encryption
- Fingerprint Generation
- Release Notes
The Virgil SDK is provided as a package named Virgil.SDK. The package is distributed via NuGet package management system.
- .NET Framework 4.0 and newer.
- Visual Studio 2013 RTM Update 2 and newer (Windows)
- Xamarin Studio 5.x and newer (Windows, Mac)
- MonoDevelop 4.x and newer (Windows, Mac, Linux)
- Use NuGet Package Manager (Tools -> Library Package Manager -> Package Manager Console)
- Run
PM> Install-Package Virgil.SDK
When you register an application on the Virgil developer's dashboard, we provide you with an appID, appKey and accessToken.
- appID uniquely identifies your application in our services, it is also used to identify the Public key generated in a pair with appKey, for example:
af6799a2f26376731abb9abf32b5f2ac0933013f42628498adb6b12702df1a87 - appKey is a Private key that is used to perform creation and revocation of Virgil Cards (Public key) in Virgil services. Also the appKey can be used for cryptographic operations to take part in application logic. The appKey is generated at the time of creation application and has to be saved in secure place.
- accessToken is a unique string value that provides an authenticated secure access to the Virgil services and is passed with each API call. The accessToken also allows the API to associate your app’s requests with your Virgil developer’s account.
Before you can use any Virgil services features in your app, you must first initialize VirgilClient class. You use the VirgilClient object to get access to Create, Revoke and Search for Virgil Cards (Public keys).
To create an instance of VirgilClient class, just call its constructor with your application's accessToken which you generated on developer's deshboard.
Namespace: Virgil.SDK.Client
var client = new VirgilClient("[YOUR_ACCESS_TOKEN_HERE]");you can also customize initialization using your own parameters
var parameters = new VirgilClientParams("[YOUR_ACCESS_TOKEN_HERE]");
parameters.SetCardsServiceAddress("https://cards.virgilsecurity.com");
parameters.SetReadCardsServiceAddress("https://cards-ro.virgilsecurity.com");
parameters.SetIdentityServiceAddress("https://identity.virgilsecurity.com");
var client = new VirgilClient(parameters);The VirgilCrypto class provides cryptographic operations in applications, such as hashing, signature generation and verification, and encryption and decryption.
Namespace: Virgil.SDK.Cryptography
var crypto = new VirgilCrypto();A Virgil Card is the main entity of the Virgil services, it includes the information about the user and his public key. The Virgil Card identifies the user/device by one of his types.
Collect an appID and appKey for your app. These parametes are required to create a Virgil Card in your app scope.
var appID = "[YOUR_APP_ID_HERE]";
var appKeyPassword = "[YOUR_APP_KEY_PASSWORD_HERE]";
var appKeyData = File.ReadAllBytes("[YOUR_APP_KEY_PATH_HERE]");
var appKey = crypto.ImportPrivateKey(appKeyData, appKeyPassword);Generate a new Public/Private keypair using VirgilCrypto class.
var aliceKeys = crypto.GenerateKeys();Prepare request
var exportedPublicKey = crypto.ExportPublicKey(aliceKeys.PublicKey);
var createCardRequest = new CreateCardRequest("alice", "username", exportedPublicKey);then, use RequestSigner class to sign request with owner and app keys.
var requestSigner = new RequestSigner(crypto);
requestSigner.SelfSign(createCardRequest, aliceKeys.PrivateKey);
requestSigner.AuthoritySign(createCardRequest, appID, appKey);Publish a Virgil Card
var aliceCard = await client.CreateCardAsync(createCardRequest);Performs the Virgil Cards search by criteria:
- the Identities request parameter is mandatory;
- the IdentityType is optional and specifies the IdentityType of a
Virgil Cards to be found; - the Scope optional request parameter specifies the scope to perform search on. Either 'global' or 'application'. The default value is 'application';
var client = new VirgilClient("[YOUR_ACCESS_TOKEN_HERE]");
var criteria = SearchCriteria.ByIdentities("alice", "bob");
var cards = await client.SearchCardsAsync(criteria);Gets a Virgil Card by ID.
var client = new VirgilClient("[YOUR_ACCESS_TOKEN_HERE]");
var card = await client.GetСardAsync("[YOUR_CARD_ID_HERE]");This sample uses built-in CardValidator to validate cards. By default CardValidator validates only Cards Service signature.
// Initialize crypto API
var crypto = new VirgilCrypto();
var validator = new CardValidator(crypto);
// Your can also add another Public Key for verification.
// validator.AddVerifier("[HERE_VERIFIER_CARD_ID]", [HERE_VERIFIER_PUBLIC_KEY]);
// Initialize service client
var client = new VirgilClient("[YOUR_ACCESS_TOKEN_HERE]");
client.SetCardValidator(validator);
try
{
var criteria = SearchCriteria.ByIdentities("alice", "bob");
var cards = await client.SearchCardsAsync(criteria);
}
catch (CardValidationException ex)
{
// ex.InvalidCards
}Initialize required components.
var client = new VirgilClient("[YOUR_ACCESS_TOKEN_HERE]");
var crypto = new VirgilCrypto();
var requestSigner = new RequestSigner(crypto);Collect App credentials
var appID = "[YOUR_APP_ID_HERE]";
var appKeyPassword = "[YOUR_APP_KEY_PASSWORD_HERE]";
var appKeyData = File.ReadAllBytes("[YOUR_APP_KEY_PATH_HERE]");
var appKey = crypto.ImportPrivateKey(appKeyData, appKeyPassword);Prepare revocation request
var cardId = "[YOUR_CARD_ID_HERE]";
var revokeRequest = new RevokeCardRequest(cardId, RevocationReason.Unspecified);
requestSigner.AuthoritySign(revokeRequest, appID, appKey);
await client.RevokeCardAsync(revokeRequest);The following code sample illustrates keypair generation. The default algorithm is ed25519
var aliceKeys = crypto.GenerateKeys();You can export and import your Public/Private keys to/from supported wire representation.
To export Public/Private keys, simply call one of the Export methods:
var exportedPrivateKey = crypto.ExportPrivateKey(aliceKeys.PrivateKey);
var exportedPublicKey = crypto.ExportPublicKey(aliceKeys.PublicKey);To import Public/Private keys, simply call one of the Import methods:
var privateKey = crypto.ImportPrivateKey(exportedPrivateKey);
var publicKey = crypto.ImportPublicKey(exportedPublicKey);Initialize Crypto API and generate keypair.
var crypto = new VirgilCrypto();
var aliceKeys = crypto.GenerateKeys();Data encryption using ECIES scheme with AES-GCM. You can encrypt either stream or a byte array. There also can be more than one recipient
Byte Array
var plaintext = Encoding.UTF8.GetBytes("Hello Bob!");
var cipherData = crypto.Encrypt(plaintext, aliceKeys.PublicKey);Stream
using (var inputStream = new FileStream("[YOUR_FILE_PATH_HERE]", FileMode.Open))
using (var cipherStream = new FileStream("[YOUR_ENCRYPTED_FILE_PATH_HERE]", FileMode.Create))
{
crypto.Encrypt(inputStream, cipherStream, aliceKeys.PublicKey);
}You can decrypt either stream or a byte array using your private key
Byte Array
crypto.Decrypt(cipherData, aliceKeys.PrivateKey);Stream
using (var cipherStream = new FileStream("[YOUR_ENCRYPTED_FILE_PATH_HERE]", FileMode.Open))
using (var resultStream = new FileStream("[YOUR_DECRYPTED_FILE_PATH_HERE]", FileMode.Create))
{
crypto.Decrypt(cipherStream, resultStream, aliceKeys.PrivateKey);
}This section walks you through the steps necessary to use the VirgilCrypto to generate a digital signature for data and to verify that a signature is authentic.
Generate a new Public/Private keypair and data to be signed.
var crypto = new VirgilCrypto();
var alice = crypto.GenerateKeys();
// The data to be signed with alice's Private key
var data = Encoding.UTF8.GetBytes("Hello Bob, How are you?");Sign the SHA-384 fingerprint of either stream or a byte array using your private key. To generate the signature, simply call one of the sign methods:
Byte Array
var signature = crypto.Sign(data, alice.PrivateKey);Stream
var fileStream = File.Open("[YOUR_FILE_PATH_HERE]", FileMode.Open, FileAccess.Read, FileShare.None);
using (fileStream)
{
var signature = crypto.Sign(inputStream, alice.PrivateKey);
}Verify the signature of the SHA-384 fingerprint of either stream or a byte array using Public key. The signature can now be verified by calling the verify method:
Byte Array
var isValid = crypto.Verify(data, signature, alice.PublicKey);Stream
var fileStream = File.Open("[YOUR_FILE_PATH_HERE]", FileMode.Open, FileAccess.Read, FileShare.None);
using (fileStream)
{
var isValid = crypto.Verify(fileStream, signature, alice.PublicKey);
}Authenticated Encryption provides both data confidentiality and data integrity assurances to the information being protected.
var crypto = new VirgilCrypto();
var alice = crypto.GenerateKeys();
var bob = crypto.GenerateKeys();
// The data to be signed with alice's Private key
var data = Encoding.UTF8.GetBytes("Hello Bob, How are you?");var cipherData = crypto.SignThenEncrypt(data, alice.PrivateKey, bob.PublicKey);var decryptedData = crypto.DecryptThenVerify(data, bob.PrivateKey, alice.PublicKey);The default Fingerprint algorithm is SHA-256.
var crypto = new VirgilCrypto();
var fingerprint = crypto.CalculateFingerprint(content);- Please read the latest note here: https://github.com/VirgilSecurity/virgil-sdk-net/releases