{"id":21957632,"url":"https://github.com/bitbeans/streamcryptor","last_synced_at":"2025-04-07T12:08:44.640Z","repository":{"id":20694907,"uuid":"23978428","full_name":"bitbeans/StreamCryptor","owner":"bitbeans","description":"Stream encryption \u0026 decryption with libsodium and protobuf","archived":false,"fork":false,"pushed_at":"2017-03-10T18:18:43.000Z","size":5985,"stargazers_count":131,"open_issues_count":2,"forks_count":29,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-11-01T09:14:43.371Z","etag":null,"topics":["c-sharp","crypto","cryptography","libsodium","protobuf"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitbeans.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-09-12T22:05:34.000Z","updated_at":"2024-09-27T14:24:34.000Z","dependencies_parsed_at":"2022-08-19T21:20:39.389Z","dependency_job_id":null,"html_url":"https://github.com/bitbeans/StreamCryptor","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitbeans%2FStreamCryptor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitbeans%2FStreamCryptor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitbeans%2FStreamCryptor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitbeans%2FStreamCryptor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitbeans","download_url":"https://codeload.github.com/bitbeans/StreamCryptor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247648978,"owners_count":20972945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","crypto","cryptography","libsodium","protobuf"],"created_at":"2024-11-29T08:54:59.612Z","updated_at":"2025-04-07T12:08:44.621Z","avatar_url":"https://github.com/bitbeans.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# StreamCryptor [![Build status](https://img.shields.io/appveyor/ci/bitbeans/StreamCryptor.svg?style=flat-square)](https://ci.appveyor.com/project/bitbeans/streamcryptor) [![Build Status](https://img.shields.io/travis/bitbeans/StreamCryptor.svg?style=flat-square)](https://travis-ci.org/bitbeans/StreamCryptor) [![NuGet Version](https://img.shields.io/nuget/v/StreamCryptor.svg?style=flat-square)](https://www.nuget.org/packages/StreamCryptor/) [![License](http://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](https://github.com/bitbeans/StreamCryptor/blob/master/LICENSE.md)\nYou can use StreamCryptor to encrypt and decrypt files without size limit and the need to load every file completely into memory.\nStreamCryptor uses `FileStream` to read and write files in chunks, there is also an asynchronous implementations for progress reporting available: [example](../master/examples/DemoAsync.md). For more working examples check out the tests in this repository.\n\nFiles are encrypted into [SCCEF](https://github.com/bitbeans/StreamCryptor#sccef-file-format) (StreamCryptor Chunked Encrypted File) format.\nEvery file contains an `EncryptedFileHeader` some `EncryptedFileChunks` and an `EncryptedFileFooter` to prevent file manipulation.\n\nThe file serialization is realised with Google`s protobuf, it has a small overhead and offers an automatic length prefix for all file parts.\nAll cryptographic operations are performed via [libsodium-net](https://github.com/adamcaudill/libsodium-net) and thus [libsodium](https://github.com/jedisct1/libsodium)), see [Algorithm details](https://github.com/bitbeans/StreamCryptor#algorithm-details).\n\nTo protect the senders PublicKey from beeing tracked, you should use an ephemeral key pair for every file. If you do this it isn't possible to authenticate who encrypted the file!\n\n## Code Status\n\n\nStreamCryptor was subjected to a source code audit carried out by  [Cure53](https://cure53.de).\n\nFinal report (PDF): [Audit-Report StreamCryptor 04.2015](https://cure53.de/pentest-report_streamcryptor.pdf)\n\n\n## Installation\n\nThere is a [NuGet package](https://www.nuget.org/packages/StreamCryptor/) available.\n\n\n## This project uses the following libraries\n\n  * [libsodium-net] - A secure cryptographic library\n  * [protobuf-net] - Efficient binary serialization by Google\n\n\n[libsodium-net]:https://github.com/adamcaudill/libsodium-net\n[protobuf-net]:https://github.com/mgravell/protobuf-net\n\n## Requirements\n\nThis library targets **.NET 4.5**.\n\n## SCCEF file format version 2\n\n### EncryptedFileHeader\n- `Version` - Used to indicate the message format. Current version is **2**.\n- `BaseNonce` - The 16 bytes, randomly generated nonce used to generate the chunk nonces.\n- `EphemeralNonce` - The 24 byte nonce for the ephemeral secret key.\n- `Key` - The encrypted 64 byte ephemeral secret key. The first 32 bytes of the key are used to handle the encryption and decryption of the chunks. The last 32 bytes are to hash the checksums with blake2b and protect these hashes with a key.\n- `HeaderChecksum` - The header checksum to validate the header and prevent file manipulation.\n- `Filename` - The encrypted original filename, padded to 256 bytes.\n- `FilenameNonce` -  The 24 byte nonce to encrypt the filename.\n- `SenderPublicKey` - The 32 byte public key of the sender to guarantee the recipient can decrypt the file.\n- `UnencryptedFileLength` - The file length of the unencrypted file.\n\n### EncryptedFileChunk\n- `ChunkLength` - The length of the chunk in bytes.\n- `ChunkIsLast` - Marks the chunk as last in the file (there only can be one last chunk per file).\n- `ChunkChecksum` - The checksum to validate the chunk and prevent file manipulation.\n- `Chunk` - The encrypted chunk content.\n\n### EncryptedFileFooter\n- `FooterChecksum` - The footer checksum to validate the footer and prevent file manipulation.\n\n## Usage\n\n### Synchronous Methods\n\n#### Encrypt\n```csharp\npublic static string EncryptFileWithStream(byte[] senderPrivateKey, byte[] senderPublicKey, byte[] recipientPublicKey, string inputFile, string outputFolder = null, string fileExtension = DEFAULT_FILE_EXTENSION, bool maskFileName = false)\n```\n\n```csharp\npublic static string EncryptFileWithStream(KeyPair senderKeyPair, byte[] recipientPublicKey, string inputFile, string outputFolder = null, string fileExtension = DEFAULT_FILE_EXTENSION, bool maskFileName = false)\n```\n\n```csharp\n//overloaded version (will use the senderKeyPair.PublicKey as recipientPublicKey)\npublic static string EncryptFileWithStream(KeyPair senderKeyPair, string inputFile, string outputFolder = null, string fileExtension = DEFAULT_FILE_EXTENSION, bool maskFileName = false) \n```\n#### Decrypt\n```csharp\npublic static string DecryptFileWithStream(byte[] recipientPrivateKey, string inputFile, string outputFolder, bool overWrite = false)\n```\n\n```csharp\n//overloaded version (keyPair.PublicKey will be ignored)\npublic static string DecryptFileWithStream(KeyPair keyPair, string inputFile, string outputFolder, bool overWrite = false)\n```\n\n### Asynchronous Methods\n\n#### Encrypt\n```csharp\npublic static async Task\u003cstring\u003e EncryptFileWithStreamAsync(byte[] senderPrivateKey, byte[] senderPublicKey, byte[] recipientPublicKey, string inputFile, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e encryptionProgress = null, string outputFolder = null, string fileExtension = DEFAULT_FILE_EXTENSION, bool maskFileName = false)\n```\n\n```csharp\npublic static async Task\u003cstring\u003e EncryptFileWithStream(KeyPair senderKeyPair, byte[] recipientPublicKey, string inputFile, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e encryptionProgress = null, string outputFolder = null, string fileExtension = DEFAULT_FILE_EXTENSION, bool maskFileName = false)\n```\n\n```csharp\n//overloaded version (will use the senderKeyPair.PublicKey as recipientPublicKey)\npublic static async Task\u003cstring\u003e EncryptFileWithStream(KeyPair senderKeyPair, string inputFile, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e encryptionProgress = null, string outputFolder = null, string fileExtension = DEFAULT_FILE_EXTENSION, bool maskFileName = false) \n```\n#### Decrypt\n```csharp\npublic static async Task\u003cstring\u003e DecryptFileWithStreamAsync(byte[] recipientPrivateKey, string inputFile, string outputFolder, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e decryptionProgress = null, bool overWrite = false)\n```\n\n```csharp\n//overloaded version (keyPair.PublicKey will be ignored)\npublic static async Task\u003cstring\u003e DecryptFileWithStream(KeyPair keyPair, string inputFile, string outputFolder, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e decryptionProgress = null, bool overWrite = false)\n```\n\nSome example code [AsyncDemo](examples/DemoAsync.md)\n\n#### Decrypt a file into memory\n```csharp\n//Method to decrypt a file and return it as DecryptedFile object\npublic static async Task\u003cDecryptedFile\u003e DecryptFileWithStreamAsync(byte[] recipientPrivateKey, string inputFile, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e decryptionProgress = null)\n```\n\n```csharp\n//overloaded version (keyPair.PublicKey will be ignored)\npublic static async Task\u003cDecryptedFile\u003e DecryptFileWithStreamAsync(KeyPair keyPair, string inputFile, IProgress\u003cStreamCryptorTaskAsyncProgress\u003e decryptionProgress = null)\n```\n\n### And some fixed parameters\n```csharp\nprivate const int CURRENT_VERSION = 2;\nprivate const int MIN_VERSION = 2;\nprivate const int CHUNK_LENGTH = 1048576; //~1MB\nprivate const int CHUNK_COUNT_START = 0;\nprivate const int CHUNK_MIN_NUMBER = 0;\nprivate const int CHUNK_BASE_NONCE_LENGTH = 16;\nprivate const int CHUNK_CHECKSUM_LENGTH = 64;\nprivate const int HEADER_CHECKSUM_LENGTH = 64;\nprivate const int FOOTER_CHECKSUM_LENGTH = 64;\nprivate const int NONCE_LENGTH = 24;\nprivate const int MAX_FILENAME_LENGTH = 256;\nprivate const int ASYNC_KEY_LENGTH = 32;\nprivate const int MASKED_FILENAME_LENGTH = 11;\nprivate const string DEFAULT_FILE_EXTENSION = \".sccef\"; //StreamCryptor Chunked Encrypted File\nprivate const string TEMP_FILE_EXTENSION = \".tmp\";\n```\n\n## Chunk length\n\nI have done some time tests with different CHUNK_LENGTH`s and a **1GB** testfile, here are the results on **my** system:\n\n|             | 524288      | 1048576     | 52428800    | 104857600   |\n| :----------- | :-----------: | :-----------: | :-----------: | :-----------: |\n| **Encrypt**     | ~26s        | ~26s        | ~32s        | ~32s        |\n| **Decrypt**     | ~26s        | ~25s        | ~28s        |   ~28s      |\n\n## File overhead\n\nThe produced overhead of the encrypted files:\n\n|             | 1 KB      | 1 MB     | 100 MB    | 1000 MB   |\n| :----------- | :-----------: | :-----------: | :-----------: | :-----------: |\n| **Encrypted**     | +83%        | +0.1%        | +0.01%        |   +0.01%      |\n\n## Algorithm details\n\n|             | Using      | libsodium     | \n| :----------------------- | :-----------: | :-----------: | :-----------: |\n| **Hashing (checksums)**    | Blake2b        |[documentation](http://bitbeans.gitbooks.io/libsodium-net/content/hashing/generic_hashing.html) | \n| **Secret-key authenticated encryption**     | XSalsa20/Poly1305 MAC        | [documentation](http://bitbeans.gitbooks.io/libsodium-net/content/secret-key_cryptography/authenticated_encryption.html)       | \n| **Public-key authenticated encryption**    | XSalsa20/Poly1305 MAC/Curve25519        | [documentation](http://bitbeans.gitbooks.io/libsodium-net/content/public-key_cryptography/authenticated_encryption.html)        |\n\n## Why\nInspired by https://github.com/jedisct1/libsodium/issues/141 and the [nacl-stream-js](https://github.com/dchest/nacl-stream-js) project.\n\n## Example\n\nSee [SccefDecryptor](https://github.com/bitbeans/SccefDecryptor)\n\n## License\n[MIT](https://en.wikipedia.org/wiki/MIT_License)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitbeans%2Fstreamcryptor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitbeans%2Fstreamcryptor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitbeans%2Fstreamcryptor/lists"}