<commit_before># Quickstart Python

- [Introduction](#introduction)
- [Obtaining an Access Token](#obtaining-an-access-token)
- [Install](#install)
- [Use case](#use-case)
    - [Initialization](#initialization)
    - [Step 1. Create and Publish the Keys](#step-1-create-and-publish-the-keys)
    - [Step 2. Encrypt and Sign](#step-2-encrypt-and-sign)
    - [Step 3. Send a Message](#step-3-send-a-message)
    - [Step 4. Receive a Message](#step-4-receive-a-message)
    - [Step 5. Get Sender's Card](#step-5-get-senders-card)
    - [Step 6. Verify and Decrypt](#step-6-verify-and-decrypt)
- [See also](#see-also)

## Introduction

This guide will help you get started using the Crypto Library and Virgil Keys Services for the most popular platforms and languages.
This branch focuses on the Python library implementation and covers its usage.

Let's build an encrypted mail exchange system as one of the possible [use cases](#use-case) of Virgil Security Services. ![Use case mail](https://raw.githubusercontent.com/VirgilSecurity/virgil/master/images/Email-diagram.jpg)

## Obtaining an Access Token

First you must create a free Virgil Security developer's account by signing up [here](https://developer.virgilsecurity.com/account/signup). Once you have your account you can [sign in](https://developer.virgilsecurity.com/account/signin) and generate an access token for your application.

The access token provides authenticated secure access to Virgil Keys Services and is passed with each API call. The access token also allows the API to associate your app's requests with your Virgil Security developer's account.

Use this token to initialize the SDK client [here](#initialization).

## Install

To install package use the command below:

```
python setup.py install
```

or you can use pip do download and install package automatically:

```
pip install virgil_sdk
```

You can easily add an SDK dependency to your project, just add the following code:

```python
from VirgilSDK import virgilhub
import VirgilSDK.virgil_crypto.cryptolib as cryptolib
```

## Use Case
**Secure any data end to end**: users need to securely exchange information (text messages, files, audio, video etc) while enabling both in transit and at rest protection.

- Application generates public and private key pairs using Virgil Crypto library and use Virgil Keys service to enable secure end to end communications:
	- public key on Virgil Public Keys Service;
	- private key on Virgil Private Keys Service or locally.
- Sender’s information is encrypted in Virgil Crypto Library with the recipient’s public key.
- Sender’s encrypted information is signed with his private key in Virgil Crypto Library.
- Application securely transfers the encrypted data, sender’s digital signature and UDID to the recipient without any risk to be revealed.
- Application on the recipient’s side verifies that the signature of transferred data is valid using the signature and sender’s public key in Virgil Crypto Library.
- Received information is decrypted with the recipient’s private key using Virgil Crypto Library.
- Decrypted data is provided to the recipient.

## Initialization

```python
identity_link = '%IDENTITY_SERVICE_URL%'
virgil_card_link = '%VIRGIL_CARD_SERVICE_URL%'
private_key_link = '%PRIVATE_KEY_SERVICE_URL%'
virgil_hub = virgilhub.VirgilHub('%ACCESS_TOKEN%', 
								identity_link, 
								virgil_card_link, 
								private_key_link)
```

## Step 1. Create and Publish the Keys
First a mail exchange application is generating the keys and publishing them to the Public Keys Service where they are available in an open access for other users (e.g. recipient) to verify and encrypt the data for the key owner.

The following code example creates a new public/private key pair.

```python
keys = cryptolib.CryptoWrapper.generate_keys
		(cryptolib.crypto_helper.VirgilKeyPair.Type_EC_SECP521R1, 
		'%PASSWORD%') 
```

The app is verifying whether the user really owns the provided email address and getting a temporary token for public key registration on the Public Keys Service.

```python
verifyResponse = virgil_hub.identity.verify('email', 
										'<EMAIL>')
# use confirmation code sent to your email box.
identResponse = virgil_hub.identity.confirm('%CONFIRMATION_CODE%', 
										verifyResponse['action_id'])
```
The app is registering a Virgil Card which includes a public key and an email address identifier. The card will be used for the public key identification and searching for it in the Public Keys Service.

```python
data ={'Field1': 'Data1', 'Field2': 'Data2'}
new_card = virgil_hub.virgilcard.create_card
							('email',
							'<EMAIL>',
							data,
							identResponse['validation_token'],
							keys['private_key'],
							'%PASSWORD%',
							keys['public_key'])
```

## Step 2. Encrypt and Sign
The app is searching for the recipient’s public key on the Public Keys Service to encrypt a message for him. The app is signing the encrypted message with sender’s private key so that the recipient can make sure the message had been sent from the declared sender.

```python
message = "Encrypt me, Please!!!";
recipient_cards = virgil_hub.virgilcard.search_card
							('<EMAIL>')
for card in recipient_cards:
  encrypted_message = cryptolib.CryptoWrapper.encrypt
  										(message, 
  										card['id'],
  										card['public_key']['public_key'])
  crypto_signature = cryptolib.CryptoWrapper.sign
  										(message, 
  										keys['private_key'], 
  										'%PASSWORD%')
```

## Step 3. Send a Message
The app is merging the message text and the signature into one structure and sending the message to the recipient using a simple IP messaging client.

```python
encryptedBody = {
    'Content' = encrypted_messages,
    'Signature' = crypto_signature
}
encryptedBodyJson = json.dumps(encryptedBody)
currentChannel.Send("<EMAIL>@<EMAIL>", 
				encryptedBodyJson)
```

## Step 4. Receive a Message
An encrypted message is received on the recipient’s side using an IP messaging client.

```python
var message = currentChannel.GetMessage()
var encryptedBody = json.loads(message.Body)
```

## Step 5. Get Sender's Card
In order to decrypt the received data the app on recipient’s side needs to get sender’s Virgil Card from the Public Keys Service.

```python
senderCard = virgil_hub.virgilcard.search_card(email.From, 'email')
```

## Step 6. Verify and Decrypt
We are making sure the letter came from the declared sender by getting his card on Public Keys Service. In case of success we are decrypting the letter using the recipient's private key.

```python
is_valid = cryptolib.CryptoWrapper.verify(encryptedBody['Content'],
										encryptedBody['Signature'],
										senderCard['public_key']['public_key'])
if not is_valid:
    raise ValueError("Signature is not valid.")

data = cryptolib.CryptoWrapper.decrypt(encryptedBody['Content'],
									 '%RECIPIENT_ID%', 
									 recipientKeyPair['private_key'], 
									 '%PASSWORD%')
```


## See Also

* [Tutorial Crypto Library](crypto.md)
* [Tutorial Keys SDK](keys.md)
<commit_msg>Update quickstart.md<commit_after># Quickstart Python

- [Introduction](#introduction)
- [Obtaining an Access Token](#obtaining-an-access-token)
- [Install](#install)
- [Use case](#use-case)
    - [Initialization](#initialization)
    - [Step 1. Create and Publish the Keys](#step-1-create-and-publish-the-keys)
    - [Step 2. Encrypt and Sign](#step-2-encrypt-and-sign)
    - [Step 3. Send a Message](#step-3-send-a-message)
    - [Step 4. Receive a Message](#step-4-receive-a-message)
    - [Step 5. Get Sender's Card](#step-5-get-senders-card)
    - [Step 6. Verify and Decrypt](#step-6-verify-and-decrypt)
- [See also](#see-also)

## Introduction

This guide will help you get started using the Crypto Library and Virgil Keys Services for the most popular platforms and languages.
This branch focuses on the Python library implementation and covers its usage.

Let's build an encrypted mail exchange system as one of the possible [use cases](#use-case) of Virgil Security Services. ![Use case mail](https://raw.githubusercontent.com/VirgilSecurity/virgil/master/images/Email-diagram.jpg)

## Obtaining an Access Token

First you must create a free Virgil Security developer's account by signing up [here](https://developer.virgilsecurity.com/account/signup). Once you have your account you can [sign in](https://developer.virgilsecurity.com/account/signin) and generate an access token for your application.

The access token provides authenticated secure access to Virgil Keys Services and is passed with each API call. The access token also allows the API to associate your app's requests with your Virgil Security developer's account.

Use this token to initialize the SDK client [here](#initialization).

## Install

To install package use the command below:

```
python setup.py install
```

or you can use pip to download and install package automatically:

```
pip install virgil_sdk
```

You can easily add an SDK dependency to your project, just add the following code:

```python
from VirgilSDK import virgilhub
import VirgilSDK.virgil_crypto.cryptolib as cryptolib
```

## Use Case
**Secure any data end to end**: users need to securely exchange information (text messages, files, audio, video etc) while enabling both in transit and at rest protection.

- Application generates public and private key pairs using Virgil Crypto library and use Virgil Keys service to enable secure end to end communications:
	- public key on Virgil Public Keys Service;
	- private key on Virgil Private Keys Service or locally.
- Sender’s information is encrypted in Virgil Crypto Library with the recipient’s public key.
- Sender’s encrypted information is signed with his private key in Virgil Crypto Library.
- Application securely transfers the encrypted data, sender’s digital signature and UDID to the recipient without any risk to be revealed.
- Application on the recipient’s side verifies that the signature of transferred data is valid using the signature and sender’s public key in Virgil Crypto Library.
- Received information is decrypted with the recipient’s private key using Virgil Crypto Library.
- Decrypted data is provided to the recipient.

## Initialization

```python
identity_link = '%IDENTITY_SERVICE_URL%'
virgil_card_link = '%VIRGIL_CARD_SERVICE_URL%'
private_key_link = '%PRIVATE_KEY_SERVICE_URL%'
virgil_hub = virgilhub.VirgilHub('%ACCESS_TOKEN%', 
								identity_link, 
								virgil_card_link, 
								private_key_link)
```

## Step 1. Create and Publish the Keys
First a mail exchange application is generating the keys and publishing them to the Public Keys Service where they are available in an open access for other users (e.g. recipient) to verify and encrypt the data for the key owner.

The following code example creates a new public/private key pair.

```python
keys = cryptolib.CryptoWrapper.generate_keys
		(cryptolib.crypto_helper.VirgilKeyPair.Type_EC_SECP521R1, 
		'%PASSWORD%') 
```

The app is verifying whether the user really owns the provided email address and getting a temporary token for public key registration on the Public Keys Service.

```python
verifyResponse = virgil_hub.identity.verify('email', 
										'<EMAIL>')
# use confirmation code sent to your email box.
identResponse = virgil_hub.identity.confirm('%CONFIRMATION_CODE%', 
										verifyResponse['action_id'])
```
The app is registering a Virgil Card which includes a public key and an email address identifier. The card will be used for the public key identification and searching for it in the Public Keys Service.

```python
data ={'Field1': 'Data1', 'Field2': 'Data2'}
new_card = virgil_hub.virgilcard.create_card
							('email',
							'<EMAIL>',
							data,
							identResponse['validation_token'],
							keys['private_key'],
							'%PASSWORD%',
							keys['public_key'])
```

## Step 2. Encrypt and Sign
The app is searching for the recipient’s public key on the Public Keys Service to encrypt a message for him. The app is signing the encrypted message with sender’s private key so that the recipient can make sure the message had been sent from the declared sender.

```python
message = "Encrypt me, Please!!!";
recipient_cards = virgil_hub.virgilcard.search_card
							('<EMAIL>')
for card in recipient_cards:
  encrypted_message = cryptolib.CryptoWrapper.encrypt
  										(message, 
  										card['id'],
  										card['public_key']['public_key'])
  crypto_signature = cryptolib.CryptoWrapper.sign
  										(message, 
  										keys['private_key'], 
  										'%PASSWORD%')
```

## Step 3. Send a Message
The app is merging the message text and the signature into one structure and sending the message to the recipient using a simple IP messaging client.

```python
encryptedBody = {
    'Content' = encrypted_messages,
    'Signature' = crypto_signature
}
encryptedBodyJson = json.dumps(encryptedBody)
currentChannel.Send("<EMAIL>", 
				encryptedBodyJson)
```

## Step 4. Receive a Message
An encrypted message is received on the recipient’s side using an IP messaging client.

```python
var message = currentChannel.GetMessage()
var encryptedBody = json.loads(message.Body)
```

## Step 5. Get Sender's Card
In order to decrypt the received data the app on recipient’s side needs to get sender’s Virgil Card from the Public Keys Service.

```python
senderCard = virgil_hub.virgilcard.search_card(email.From, 'email')
```

## Step 6. Verify and Decrypt
We are making sure the letter came from the declared sender by getting his card on Public Keys Service. In case of success we are decrypting the letter using the recipient's private key.

```python
is_valid = cryptolib.CryptoWrapper.verify(encryptedBody['Content'],
										encryptedBody['Signature'],
										senderCard['public_key']['public_key'])
if not is_valid:
    raise ValueError("Signature is not valid.")

data = cryptolib.CryptoWrapper.decrypt(encryptedBody['Content'],
									 '%RECIPIENT_ID%', 
									 recipientKeyPair['private_key'], 
									 '%PASSWORD%')
```


## See Also

* [Tutorial Crypto Library](crypto.md)
* [Tutorial Keys SDK](keys.md)

{'fraction_non_alphanumeric': 0.08734918507020391, 'fraction_numerical': 0.003668947999717773, 'mean_word_length': 4.236054673069819, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '304656', 'n_tokens_mistral': 4495, 'n_tokens_neox': 3851, 'n_words': 1591}