feistel

package module
v1.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2021 License: MIT Imports: 8 Imported by: 10

README

feistel

GitHub tag (latest by date) GitHub last commit GitHub issues GitHub license

This is a Golang library implementing the Feistel cipher for Format-Preserving Encryption (FPE).

Motivation

The main objective of this library is not to provide a secure encryption scheme but rather a safe obfuscation tool.

Formal description

This library operates on the concept of the Feistel cipher described in Wikipedia as:

A Feistel network is subdivided into several rounds or steps. In its balanced version, the network processes the data in two parts of identical size. On each round, the two blocks are exchanged, then one of the blocks is combined with a transformed version of the other block. Half of the data is encoded with the key, then the result of this operation is added using an XOR operation to the other half of the data. Then in the next round, we reverse: it is the turn of the last half to be encrypted and then to be xored to the first half, except that we use the data previously encrypted. The diagram below shows the data flow (the represents the XOR operation). Each round uses an intermediate key, usually taken from the main key via a generation called key schedule. The operations performed during encryption with these intermediate keys are specific to each algorithm.

The algorithmic description (provided by Wikipedia) of the encryption is as follows:

  • Let be the number of steps, the keys associated with each step and a function of the space to the space.
  • For each step , note the encrypted word in step :
  • is the unciphered text, is the ciphered word.

There is no restriction on the function other than the XOR operation must be possible. For simplicity, we will choose of the same size as and the function shall transform a word of length into a word of length (and this for all ).

Usage
go get github.com/cyrildever/feistel

To get an obfuscated string from a source data using an automatic key generation from SHA-256 hashing function at each round, first instantiate a Cipher object, passing it a base key and a number of rounds. Then, use the Encrypt() method with the source data as argument. The result will be a byte array. To ensure maximum security, I recommend you use a 256-bit key or longer and a minimum of 10 rounds.

The decryption process uses the obfuscated byte array and pass it to the Decrypt() method of the Cipher.

import "github.com/cyrildever/feistel"

source := "my-source-data"

// Encrypt
cipher := feistel.NewCipher("some-32-byte-long-key-to-be-safe", 10)
obfuscated, err := cipher.Encrypt(source)

// Decrypt
deciphered, err := cipher.Decrypt(obfuscated)

assert.Equal(t, deciphered, source)

NB: This is the exact replica of my Typescript implementation (see below).

You may also use your own set of keys through a CustomCipher instance, eg.

keys := []string{
  "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
  "9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba",
  "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
}
cipher = feistel.NewCustomCipher(keys)

In that case, the number of rounds depends on the number of provided keys.

Finally, you might want to use the latest cipher, providing true format-preserving encryption for strings:

import "github.com/cyrildever/feistel/common/utils/hash"

cipher = feistel.NewFPECipher(hash.SHA_256, "some-32-byte-long-key-to-be-safe", 128)

obfuscated, err := cipher.Encrypt(source)

str := obfuscated.String()
assert.Equal(t, len(str), len(source))
Other implementations

For those interested, I also made another implementation of these ciphers in Typescript.

I also created a special library for redacting classified documents using the new FPE cipher. Feel free to contact me about it.

White papers

I wrote two white papers to finally make it a fully FPE scheme:

  • the original one which provided an "almost" format-preserving encryption;
  • the lastest one which elaborates on this first one to push the algorithm towards true format-preserving encryption for strings.
License

This module is distributed under an MIT license. See the LICENSE file.


© 2019-2021 Cyril Dever. All rights reserved.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cipher

type Cipher struct {
	Key    string
	Rounds int
}

Cipher uses the SHA-256 hashing function to create the keys at each round. NB: There must be at least 2 rounds.

func NewCipher

func NewCipher(key string, rounds int) *Cipher

NewCipher ...

func (Cipher) Decrypt

func (c Cipher) Decrypt(ciphered []byte) (string, error)

Decrypt ...

func (Cipher) Encrypt

func (c Cipher) Encrypt(src string) (ciphered []byte, err error)

Encrypt ...

type CustomCipher added in v1.1.0

type CustomCipher struct {
	Keys []string
}

CustomCipher uses custom keys instead of the SHA-256 hashing function to provide a new key at each round. The number of rounds is then determined by the number of keys provided. NB: There must be at least two keys.

func NewCustomCipher added in v1.1.0

func NewCustomCipher(keys []string) *CustomCipher

NewCustomCipher ...

func (CustomCipher) Decrypt added in v1.1.0

func (cc CustomCipher) Decrypt(ciphered []byte) (string, error)

Decrypt ...

func (CustomCipher) Encrypt added in v1.1.0

func (cc CustomCipher) Encrypt(src string) (ciphered []byte, err error)

Encrypt ...

type FPECipher added in v1.3.0

type FPECipher struct {
	Engine hash.Engine
	Key    string
	Rounds int
}

FPECipher builds a format-preserving encrypted cipher using the key with the passed hash engine at each round. NB: There must be at least 2 rounds.

func NewFPECipher added in v1.3.0

func NewFPECipher(engine hash.Engine, key string, rounds int) *FPECipher

NewFPECipher ...

func (FPECipher) Decrypt added in v1.3.0

func (f FPECipher) Decrypt(ciphered base256.Readable) (string, error)

Decrypt ...

func (FPECipher) Encrypt added in v1.3.0

func (f FPECipher) Encrypt(src string) (ciphered base256.Readable, err error)

Encrypt ...

Directories

Path Synopsis
common

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL