# Magic Encryption

**Keep a value opaque at rest on the device.**

AES-256-CBC for apps on the Magic framework, through the `Crypt` facade. Payloads are not authenticated and not compatible with Laravel's encrypter.

## One facade. Two keys.

`Crypt` encrypts with your `APP_KEY` or with a per-device key kept in Vault. It keeps a value opaque at rest; it does not authenticate it.

### Encrypt and decrypt

`Crypt.encrypt(value)` and `Crypt.decrypt(payload)` use the app key, with AES-256 in CBC mode and PKCS7 padding.

[Learn more about Encrypt and decrypt](https://anilcancakir.com/magic/docs/encryption/basics/crypt.md)

### The app key

The key is 32 raw characters or a `base64:` value that decodes to 32 bytes. The encrypter resolves it lazily from `app.key`. The key ships inside every build, so it hides a value from someone without the app, not from someone who unpacks it.

[Learn more about The app key](https://anilcancakir.com/magic/docs/encryption/basics/app-key.md)

### A per-device key

`Crypt.encryptWithDeviceKey` and `Crypt.decryptWithDeviceKey` use a key kept in Vault. Manage it with `hasDeviceKey`, `generateDeviceKey` and `clearDeviceKey`.

[Learn more about A per-device key](https://anilcancakir.com/magic/docs/encryption/basics/device-key.md)

### What is on the wire

Every call uses a fresh random 16-byte IV, and the payload is `base64(iv):base64(ciphertext)`. It has no MAC, no key id and no rotation, and it is not Laravel's format.

[Learn more about What is on the wire](https://anilcancakir.com/magic/docs/encryption/guides/wire-format.md)

### Errors are exceptions

A payload that cannot be decrypted throws `MagicDecryptException`. Encrypting an empty string throws a `RangeError`.

[Learn more about Errors are exceptions](https://anilcancakir.com/magic/docs/encryption/basics/crypt.md)

### Generate the key

`dart run magic:dowel key:generate` writes `APP_KEY=base64:...` into `.env`. Pass `--show` to print the key instead. It replaces any existing key, and values encrypted under the old one become unreadable.

[Learn more about Generate the key](https://anilcancakir.com/magic/docs/encryption/basics/app-key.md)

## Add it in seconds

```bash
flutter pub add magic_encryption
```

Or add to `pubspec.yaml`:

```yaml
dependencies:
  magic_encryption: ^1.0.2
```

Or give your AI agent this prompt:

```text
Read https://anilcancakir.com/magic/docs/encryption/llms.txt and install the Magic Encryption package in this project.
```

## Docs

### Getting Started

- [Installation](https://anilcancakir.com/magic/docs/encryption/getting-started/installation.md)

### The Basics

- [Crypt](https://anilcancakir.com/magic/docs/encryption/basics/crypt.md)
- [App Key](https://anilcancakir.com/magic/docs/encryption/basics/app-key.md)
- [Device Key](https://anilcancakir.com/magic/docs/encryption/basics/device-key.md)

### Guides

- [Wire Format](https://anilcancakir.com/magic/docs/encryption/guides/wire-format.md)
- [Testing](https://anilcancakir.com/magic/docs/encryption/guides/testing.md)
