|
| 1 | +# Encrypting a String |
| 2 | + |
| 3 | +After connecting to the Lit Network and authenticating a session, you can encrypt a string using the Lit SDK's [encrypt](https://v6-api-doc-lit-js-sdk.vercel.app/classes/lit_node_client_src.LitNodeClientNodeJs.html#encrypt) method. This method takes in the string, as an array of bytes, you want to encrypt, as well as an array of [Access Control Conditions (ACCs)](https://developer.litprotocol.com/docs/advanced-topics/access-control-conditions) that specify who is authorized to decrypt the data. |
| 4 | + |
| 5 | +Encryption happens client side, as the instance of `LitNodeClient` you created has retrieved the public BLS key for the Lit Network you are connected to. |
| 6 | + |
| 7 | +When you want to decrypt the string, you will submit the _encryption metadata_ (ciphertext, dataToEncryptHash, and access control conditions) and your Session Signatures to the Lit Network. Each Lit node will verify that you have the necessary permissions to decrypt the data (by parsing the access control conditions the data was encrypted with) and then generate their decryption shares if authorized. Once all the decryption shares are generated, they are returned back to the client where the Lit SDK will combine them and return the decrypted string. |
| 8 | + |
| 9 | +- [Encrypting a String](#encrypting-a-string) |
| 10 | + - [Prerequisites](#prerequisites) |
| 11 | + - [Running the Code Example](#running-the-code-example) |
| 12 | + - [Requirements](#requirements) |
| 13 | + - [Steps](#steps) |
| 14 | + - [Expected Output](#expected-output) |
| 15 | + - [Understanding the Code](#understanding-the-code) |
| 16 | + - [Creating an Ethers signer](#creating-an-ethers-signer) |
| 17 | + - [Defining the Access Control Conditions](#defining-the-access-control-conditions) |
| 18 | + - [Encrypting the Data](#encrypting-the-data) |
| 19 | + - [Requesting Session Signatures](#requesting-session-signatures) |
| 20 | + - [Decrypting the Data](#decrypting-the-data) |
| 21 | + - [Next Steps](#next-steps) |
| 22 | + |
| 23 | +## Prerequisites |
| 24 | + |
| 25 | +- Understanding of Lit core terminology and concepts covered [here](../README.md#core-terminology) |
| 26 | +- Understanding of Lit encryption terminology and concepts covered [here](../README.md#relevant-terminology) |
| 27 | +- Understanding of the [Connecting to the Lit Network](../connecting-to-lit/README.md) guide |
| 28 | +- Understanding of the [Authenticating a Session](../../_getting-started/authenticating-a-session/README.md) guide |
| 29 | + |
| 30 | +## Running the Code Example |
| 31 | + |
| 32 | +### Requirements |
| 33 | + |
| 34 | +- [Node.js](https://nodejs.org/en) |
| 35 | +- [Yarn](https://yarnpkg.com/getting-started) |
| 36 | +- `@lit-protocol/constants` |
| 37 | +- `@lit-protocol/lit-node-client` |
| 38 | +- `@lit-protocol/auth-helpers` |
| 39 | +- `@lit-protocol/types` |
| 40 | + |
| 41 | +### Steps |
| 42 | + |
| 43 | +1. `yarn` to install the dependencies |
| 44 | +2. `yarn test` to run the code example |
| 45 | + |
| 46 | +### Expected Output |
| 47 | + |
| 48 | +After running the code example, you should see output in your terminal: |
| 49 | + |
| 50 | +1. An indication that a connection to the Lit Network was successfully established |
| 51 | +2. The string was successfully encrypted |
| 52 | + - The `ciphertext` and `dataToEncryptHash` are logged to the terminal for demonstration purposes: |
| 53 | + |
| 54 | +```bash |
| 55 | +ℹ️ ciphertext: mRLJXD7wAMsvBoq9Gb60bn+ofuZ0srzdU/cEkSvagDvwCr3X5l1tUNuHUXgTrLGbiv/iT7o7qtJ73pFQwRmjpmH4bQ2klUGEvdgTUElrHtQ4SSfSrqYY5tciNjmIip7ifS7oNnHMArK2vuld6ZVqW8VnonSNyVdefaxckYLAovxdVrssUi7U2okC |
| 56 | +ℹ️ dataToEncryptHashh: 5ad8f16e45a2f21c693ea4e9376e46424abbf8f74838a5bd8f6173c54ba2e87a |
| 57 | +``` |
| 58 | + |
| 59 | +3. Session Signatures were successfully generated for the requested session |
| 60 | +4. After the JavaScript test passes, you should see the decrypted string logged to the terminal: |
| 61 | + |
| 62 | +```bash |
| 63 | +ℹ️ decryptedString: The answer to life, the universe, and everything is 42. |
| 64 | +``` |
| 65 | + |
| 66 | +## Understanding the Code |
| 67 | + |
| 68 | +The following code from [./src/index.ts](./src/index.ts) does the following: |
| 69 | + |
| 70 | +### Creating an Ethers signer |
| 71 | + |
| 72 | +As covered in the [Authenticating a Session](../../_getting-started/authenticating-a-session/README.md#creating-an-ethers-signer) guide, the `ethersSigner` is used to generate an Authentication Signature which is a [ERC-5573](https://eips.ethereum.org/EIPS/eip-5573) message that specifies what Lit Resources and corresponding abilities the Session will be authorized to use. |
| 73 | + |
| 74 | +### Defining the Access Control Conditions |
| 75 | + |
| 76 | +The following are the Access Control Conditions that we are using as part of the encryption process. They specify that the data can only be decrypted by the Ethereum address that corresponds to the `ethersSigner` we created earlier: |
| 77 | + |
| 78 | +```typescript |
| 79 | +const accessControlConditions: AccessControlConditions = [ |
| 80 | + { |
| 81 | + contractAddress: "", |
| 82 | + standardContractType: "", |
| 83 | + chain: "ethereum", |
| 84 | + method: "", |
| 85 | + parameters: [":userAddress"], |
| 86 | + returnValueTest: { |
| 87 | + comparator: "=", |
| 88 | + value: await ethersSigner.getAddress(), |
| 89 | + }, |
| 90 | + }, |
| 91 | +]; |
| 92 | +``` |
| 93 | + |
| 94 | +These conditions are what you'll want to customize based on your project's use case. You can learn more about the different types of conditions available [here](https://developer.litprotocol.com/category/advanced-topics). |
| 95 | + |
| 96 | +### Encrypting the Data |
| 97 | + |
| 98 | +The following code is what actually encrypts the data using the Lit SDK and the Lit network's public BLS key: |
| 99 | + |
| 100 | +```typescript |
| 101 | +const { ciphertext, dataToEncryptHash } = await litNodeClient.encrypt({ |
| 102 | + dataToEncrypt: new TextEncoder().encode( |
| 103 | + "The answer to life, the universe, and everything is 42." |
| 104 | + ), |
| 105 | + accessControlConditions, |
| 106 | +}); |
| 107 | + |
| 108 | +console.log(`ℹ️ ciphertext: ${ciphertext}`); |
| 109 | +console.log(`ℹ️ dataToEncryptHashh: ${dataToEncryptHash}`); |
| 110 | +``` |
| 111 | + |
| 112 | +`dataToEncrypt` takes a `Uint8Array` as an argument, so we need to convert the string to a `Uint8Array` using `new TextEncoder().encode`. |
| 113 | + |
| 114 | +The output of the `encrypt` method is the `ciphertext` and `dataToEncryptHash`. Coupled with the `accessControlConditions`, this forms the _encryption metadata_ that we'll need to submit to the Lit Network when we want to decrypt the data later. |
| 115 | + |
| 116 | +### Requesting Session Signatures |
| 117 | + |
| 118 | +Our request for session signatures is the same as covered in the [Authenticating a Session](../../_getting-started/authenticating-a-session/README.md#requesting-session-signatures) guide. |
| 119 | + |
| 120 | +However, one thing to note is that the signer of the ERC-5573 message is identity the Lit nodes will use when performing the authorization check for our decryption request. In other words, the Ethereum address derived from the Authentication Signature is what will be checked against the `accessControlConditions` we defined earlier. This derived address **must** match what we specified as `returnValueTest.value` (in the case of this example, that's `await ethersSigner.getAddress()`). |
| 121 | + |
| 122 | +### Decrypting the Data |
| 123 | + |
| 124 | +Lastly, we call the `decrypt` method to decrypt the data. This method takes in the encryption metadata and your Session Signatures as arguments. Similar to when requesting Session Signatures, the `chain` argument signals the signature schema and message format that the Lit nodes will use to authenticate the decryption request (and should almost always be `ethereum`). |
| 125 | + |
| 126 | +Finally the decryption response is returned which is an object with the `Uint8Array` property: `decryptedData`. We can convert this back to a string by calling `new TextDecoder().decode` to get our decrypted string. |
| 127 | + |
| 128 | +```typescript |
| 129 | +const decryptionResponse = await litNodeClient.decrypt({ |
| 130 | + chain: "ethereum", |
| 131 | + sessionSigs: sessionSignatures, |
| 132 | + ciphertext, |
| 133 | + dataToEncryptHash, |
| 134 | + accessControlConditions, |
| 135 | +}); |
| 136 | + |
| 137 | +const decryptedString = new TextDecoder().decode( |
| 138 | + decryptionResponse.decryptedData |
| 139 | +); |
| 140 | +console.log(`ℹ️ decryptedString: ${decryptedString}`); |
| 141 | +``` |
| 142 | + |
| 143 | +## Next Steps |
0 commit comments