[quote]create their own encryption algorithm[/quote] That’s basically what I did, using the crypto.pbkdf2 function as the keystream/pad generator (which is perfect, since you can create a hash of a given length, so you create the keystream/pad the same length of the data you’re passing to it). I originally ported of RC4 to RealBasic along time ago (http://permalink.gmane.org/gmane.comp.lang.realbasic.forums/6254) [seems the old realbasic forums are currently down, but accessible through that link]. Anyhow, creating your own encryption is frowned upon in the security sector. There’s so many things that you can do wrong, etc. and the outcomes all look the same which gives the illusion that your method is secure… when it most likely isn’t. For those truly interested in cryptography, Coursera (https://www.coursera.org/course/crypto) offers a FREE class (which I highly recommend). I’m posting the encryption methods below for anybody that want to use them (it’s extremely simple code). I use the SALT as the size of the plainText being passed to it, but you can change it to a fixed constant. I also added an integrity checksum AFTER the encryption process, to better insure the cipherText passed to the decipher function is a legitimate cipher which hasn’t been altered to tampered with. This only HELPS insure the integrity of the cipher, it does not validate whether the cipherPass or cipherIterations passed to it are correct. If you pass the wrong of either of those, it still return data… just not the original plainText.
[code]Function cipher(plainText as memoryBlock, cipherPass as memoryBlock, cipherIterations as uInt32) As memoryBlock
// - :cipher
// -
// - developer(s): eric d. brown
// - definition: decrypts content previously encrypted by using [self.cipher]; validates integerity checksum
// - revision: 2014.10.01
// - platform(s): *
const BYTE_OFFSET = 1
dim checksumContent as memoryBlock
dim cipherContent as memoryBlock
dim cipherPad as memoryBlock
dim contentIndex as uInt32
cipherContent = new memoryBlock(plainText.size) 'reserve buffer size; equals size of [plainText]
// - construct [cipherPad] from a hash variation of [cipherPass]
// - uses the size of [plainText] as the SALT
// - equals the size of and XOR’d against [plainText] to construct [cipherContent]
cipherPad = crypto.pbkdf2(str(plainText.size), cipherPass, cipherIterations, plainText.size, crypto.algorithm.sha512)
// - iterate and XOR contents of [plainText] with [cipherPad] to construct [cipherContent]
for contentIndex = ZERO_VALUE to plainText.size - BYTE_OFFSET
cipherContent.byte(contentIndex) = bitWise.bitXor(plainText.byte(contentIndex), cipherPad.byte(contentIndex))
next contentIndex
// - construct and append an integrity checksum (size set by [self.CHECKSUM_SIZE] constant)
checksumContent = crypto.pbkdf2(crypto.sha1(cipherContent), cipherContent, self.CHECKSUM_ITERATIONS, self.CHECKSUM_SIZE, crypto.algorithm.sha256)
return cipherContent + checksumContent 'return [cipherContent] with appended integrity checksum [checksumContent]
End Function[/code]
[code]Function deCipher(cipherText as memoryBlock, cipherPass as memoryBlock, cipherIterations as uInt32, byRef plainText as memoryBlock) As boolean
// - :deCipher
// -
// - developer(s): eric d. brown
// - definition: decrypts content previously encrypted by using [self.cipher]; validates integerity checksum
// - revision: 2014.10.01
// - platform(s): *
const BYTE_OFFSET = 1
dim checksumContent as memoryBlock
dim deCipherContent as memoryBlock
dim deCipherPad as memoryBlock
dim contentIndex as uInt32
if cipherText.size <= self.CHECKSUM_SIZE then '[cipherText ] is not a valid cipher; too short
return false
end if
// - construct validation checksum from contents of [cipherText], excluding the appended checksum itself
checksumContent = crypto.pbkdf2(crypto.sha1(left(cipherText, (cipherText.size - self.CHECKSUM_SIZE))), left(cipherText, _
(cipherText.size - self.CHECKSUM_SIZE)), self.CHECKSUM_ITERATIONS, self.CHECKSUM_SIZE, crypto.algorithm.sha256)
if right(cipherText, self.CHECKSUM_SIZE) = checksumContent then 'if integrity checksum is valid
// - reserve buffer size; equals size of [cipherText] minus [CHECKSUM_SIZE]
deCipherContent = new memoryBlock(cipherText.size - self.CHECKSUM_SIZE)
// - construct [deCipherPad] from a hash variation of [targetPass]
// - uses the size of [cipherText] minus [CHECKSUM_SIZE] as the SALT
// - equals the size of and XOR'd against [cipherText] to construct [deCipherContent]
deCipherPad = crypto.pbkdf2(str(cipherText.size - self.CHECKSUM_SIZE), cipherPass, cipherIterations, _
(cipherText.size - self.CHECKSUM_SIZE), crypto.algorithm.sha512)
// - iterate and XOR contents of [cipherText] with [deCipherPad] to construct [deCipherContent]
for contentIndex = ZERO_VALUE to ((cipherText.size - self.CHECKSUM_SIZE) - BYTE_OFFSET)
deCipherContent.byte(contentIndex) = bitWise.bitXor(cipherText.byte(contentIndex), deCipherPad.byte(contentIndex))
next contentIndex
plainText = deCipherContent 'return byRef [plainText]
return true
else 'integrity checksum is invalid
return false
end if
End Function[/code]
Usage example:
[code] dim plainText as memoryBlock
dim cipherText as memoryBlock
dim cipherPass as memoryBlock
plainText = “This is the datat I want to encrypt”
cipherPass = “This” + “is” + “my” + “password”
cipherText = cipher(plainText, cipherPass, 1)
if deCipher(cipherText, cipherPass, 1, plainText) then
print plainText
else
print “invalid cipher integerity checksum”
end if[/code]
Whatever cipherIterations you give it to cipher must also match what is given to properly decipher. This adds a level of security, and gives the benefits of the pbkdf2 hash itself (which is its slowness, which helps against bruteforce attacks on your cipher; however, it comes at a cost… which is performance, as pbkdf2 at higher iterations becomes linearly more slow).