有没有人能够很好地实现用纯便携式C编写的流密码?在这个时间点,我并不十分关心密码的强度,因为它只是用于概念验证,但速度很重要。如果我找不到合适的流密码,我一直在考虑使用常数Xor'ing。
答案 0 :(得分:6)
编辑(2018):如果您正在寻找更小的代码占用空间,请使用NaCl或libsodium或TweetNaCl。它们提供强大的加密,应该比RC4快得多。
RC4是一种非常简单的算法。
结帐Sterling Camden's implementation或Adam Back's implementation。
答案 1 :(得分:4)
请参阅ECRYPT eStream项目。这些是由安全专家评判的严肃的硬核加密算法。据我所知,所有候选算法都需要在纯C(而不是C ++)中包含一个实现。
编辑:该网站的优点在于它深入探讨了不同的算法,包括其已知的弱点,并且还包括performance benchmarks。
答案 2 :(得分:2)
对于纯POC应用程序,您可以快速将ROT13投入到位。 http://en.wikipedia.org/wiki/ROT13
然而,我对提出这个建议非常犹豫,因为过于频繁的简单POC代码以后永远不会被替换......
答案 3 :(得分:1)
我Blowfish没有遇到太多麻烦。它声称比DES快。
答案 4 :(得分:1)
这是C中流密码的一个非常基本的实现。不,无论如何都是安全的。它只是说明了如何执行所需的基本步骤。
真正的魔法需要在CycleKey
函数中完成,它会在每个数据块通过加密流时生成新的键值。
此示例一次加密一个char
。您必须将概念扩展到更大的数据块,以便加密到接近安全的地方。我再次这样做只是为了说明基本步骤。
祝你好运!
#include <stdio.h>
char staticKey;
void CycleKey(char data)
{
/* this is where the real magic should occur */
/* this code does *not* do a good job of it. */
staticKey += data;
if (staticKey & 0x80)
{
staticKey ^= 0xD8;
}
else
{
staticKey += 0x8B;
}
}
void ResetCipher(const char * key)
{
staticKey = 0;
while (*key)
{
CycleKey(*key);
key++;
}
}
void Encrypt(const char * plaintext, char * encrypted)
{
while (*plaintext)
{
*encrypted = *plaintext + staticKey;
CycleKey(*encrypted);
encrypted++;
plaintext++;
}
*encrypted = '\0';
}
void Decrypt(char * plaintext, const char * encrypted)
{
while (*encrypted)
{
*plaintext = *encrypted - staticKey;
CycleKey(*encrypted);
plaintext++;
encrypted++;
}
*plaintext = '\0';
}
int main(void)
{
char * key = "123";
char * message = "Hello, World!";
char encrypted[20];
char decrypted[20];
ResetCipher(key);
Encrypt(message, encrypted);
ResetCipher(key);
Decrypt(decrypted, encrypted);
printf("output: %s\n", decrypted);
return 0;
}
答案 5 :(得分:0)
你看过OpenSSL吗?它具有许多加密算法和原语的安全实现。您不必将其与网络相关的任何内容一起使用。但是,它并没有很好的记录或易于学习。如果您非常关心安全性(例如,如果您要存储私人用户数据,如信用卡),您绝对应该使用OpenSSL或其他一些安全实施,而不是自己动手。
答案 6 :(得分:0)
出于理解目的,您可以参考以下代码。该代码使用伪随机数生成器生成密钥,纯粹用C语言编写。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Function declarations */
int getSize(char *array);
int hashCode(const char *str, int size);
void convertIntToBinaryArray(int num, int *arr, int *index);
void encryptStreamCipher(int key[], int data[], int encypted_data[],int data_size);
void decryptStreamCipher(int key[], int enc_data[], int data_size);
void convertCharToBinary(char c,int *binary_arr,int *index);
void convertStringToBinary(char *str,int *binary_arr, int *size);
void convertBinaryToString(int *data,char *array_string,int *index);
char convertBinaryToChar(char *str);
void displayIntArray(int *array, int size);
void displayCharArray(char *array, int size);
#define MAX_SIZE 10000
int main(int argc, char **argv) {
char array_string[MAX_SIZE];
char ascii_key[MAX_SIZE];
int data[MAX_SIZE];
int key[MAX_SIZE];
int encypted_data[MAX_SIZE];
int seed;
int key_int;
int key_size = 0;
int index;
int data_size = 0;
/* 1. Enter the data to encrypt (Do not use space in between)*/
fprintf(stdout, "Enter data to encrypt: \n");
fscanf(stdin, "%s", array_string);
/* 2. Convert the string to binary data */
convertStringToBinary(array_string,data,&data_size);
printf("Data in binary: \n");
displayIntArray(data,data_size);
/* 3. Read the key string from user */
fprintf(stdout, "Enter key to encrypt data with: \n");
fscanf(stdin, "%s", ascii_key);
/* 4.Get hash code from the key */
key_size = getSize(ascii_key);
seed = hashCode(ascii_key, key_size);
/* 5. Set the key as seed to random number generator to create a key of random bits */
srand(seed);
key_int = rand();
/* 6. Convert key to binary int array */
convertIntToBinaryArray(key_int, key, &index);
printf("Key in binary: \n");
displayIntArray(key,index);
/* 7. Encrypt : (Binary data) XOR (Binary key) */
encryptStreamCipher(key, data, encypted_data, data_size);
/* 8. Display encrypted data */
printf("encrypted Data: \n");
displayIntArray(encypted_data,data_size);
/* 9.Now, Decrypt data and verify initial data */
decryptStreamCipher(key, encypted_data, data_size);
printf("Decrypted binary data: \n");
displayIntArray(encypted_data,data_size);
/* 10. Convert decrypted data in binary to string */
memset(array_string,0,sizeof(array_string));
convertBinaryToString(encypted_data,array_string,&data_size);
/* 11.Display the original message in string */
printf("Decrypted Data in String: \n");
displayCharArray(array_string,data_size);
return 0;
}
int getSize(char *array) {
int size = 0;
int i = 0;
while ((i != MAX_SIZE) && (array[i] != '\0')) {
i++;
size++;
}
return size;
}
int hashCode(const char *str, int size) {
int hash = 0;
for (int i = 0; i < size; i++) {
hash = 31 * hash + str[i];
}
return hash;
}
void convertIntToBinaryArray(int num, int *arr, int *index) {
if (num == 0 || *index >= MAX_SIZE)
return;
convertIntToBinaryArray(num / 2, arr, index);
if (num % 2 == 0)
arr[(*index)++] = 0;
else
arr[(*index)++] = 1;
}
void encryptStreamCipher(int key[], int data[], int encypted_data[],
int data_size) {
for (int i = 0; i < data_size; i++) {
encypted_data[i] = data[i] ^ key[i];
}
}
void decryptStreamCipher(int key[], int enc_data[], int data_size) {
for (int i = 0; i < data_size; i++) {
enc_data[i] = enc_data[i] ^ key[i];
}
}
void convertStringToBinary(char *str,int *binary_arr,int *index) {
*index=0;
for (int i = 0; i<strlen(str); i++) {
convertCharToBinary(str[i],binary_arr,index);
}
}
void convertCharToBinary(char c,int *binary_arr,int *index) {
for (int i = 7; i >= 0; --i) {
binary_arr[*index]=((c & (1 << i)) ? 1 : 0);
(*index)++;
}
}
void convertBinaryToString(int *data,char *array_string,int *index){
int data_size=*index;
char char_array[data_size];
*index=0;
for(int i=0;i<data_size;i++){
char_array[i]=(data[i] == 1?'1':'0');
}
for(int i=0;i<data_size;i=i+8){
char sub_str[8];
memcpy(sub_str,char_array+i,8);
array_string[(*index)++]=convertBinaryToChar(sub_str);
}
}
char convertBinaryToChar(char *str){
char c=strtol(str,0,2);
return c;
}
void displayIntArray(int *array, int size)
{
for (int i = 0; i < size; i++) {
printf("%d",array[i]);
}
printf("\n");
}
void displayCharArray(char *array, int size)
{
for (int i = 0; i < size; i++) {
printf("%c",array[i]);
}
printf("\n");
}
<强>输出:强>
输入要加密的数据: prateekjoshi
二进制数据:
01110000011100100110000101110100011001010110010101101011011010100110111101110011011 0100001101001
输入密钥以使用以下方式加密数据:
密码
键入二进制文件:
101010100101110000101101000101
加密数据:
11011010001011100100110001100000011001010110010101101011011010100110111101110011011 0100001101001
解密的二进制数据:
01110000011100100110000101110100011001010110010101101011011010100110111101110011011 0100001101001
字符串中的解密数据:
prateekjoshi