- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用河豚的以下实现(从中间切掉一些东西)来加密和解密消息。我试图在大端机器 (SunOS 5.10) 上加密消息,然后通过套接字将其发送到小端机器 (linux)。我可以在同一台机器和不同的 linux 机器上加密和解密,但我无法让它在这两台机器之间工作。
因为 blowfish 实现似乎将消息分解为 DWords,每个 DWords 包含两个 32 位整数,我一直在将我的加密消息分解为 32 位整数,对每个应用 htonl(),通过网络发送它们,对每个应用 ntohl(),然后尝试解密。结果并不漂亮,但有趣的是,解密后大部分正确的字符都出现了,但它们是乱码,并且在某些地方出现了一些额外的乱码。我真的无法想象我可能会错过什么。
/********** blowfish.h **********/
#ifndef ___BLOWFISH_H___
#define ___BLOWFISH_H___
#define NUM_SUBKEYS 18
#define NUM_S_BOXES 4
#define NUM_ENTRIES 256
#define MAX_STRING 256
#define MAX_PASSWD 56 // 448bits
#ifdef BIG_ENDIAN
struct WordByte
{
unsigned int zero:8;
unsigned int one:8;
unsigned int two:8;
unsigned int three:8;
};
#endif
#ifdef LITTLE_ENDIAN
struct WordByte
{
unsigned int three:8;
unsigned int two:8;
unsigned int one:8;
unsigned int zero:8;
};
#endif
union Word
{
unsigned int word;
WordByte byte;
};
struct DWord
{
Word word0;
Word word1;
};
class Blowfish
{
private:
unsigned int PA[NUM_SUBKEYS];
unsigned int SB[NUM_S_BOXES][NUM_ENTRIES];
void Gen_Subkeys(char *);
inline void BF_En(Word *,Word *);
inline void BF_De(Word *,Word *);
public:
Blowfish();
~Blowfish();
void Reset();
void Set_Passwd(char * = NULL);
void Encrypt(void *,unsigned int);
void Decrypt(void *,unsigned int);
};
#endif
/********** blowfish.cc **********/
#include <iostream.h>
#include <string.h>
#include "blowfish.h"
#define F(x) (((SB[0][x.byte.zero] + SB[1][x.byte.one]) ^ SB[2][x.byte.two]) + SB[3][x.byte.three])
void Blowfish::Gen_Subkeys(char *Passwd)
{
unsigned int i,j,len=strlen(Passwd);
Word Work,null0,null1;
if (len > 0)
{
j = 0;
for (i=0;i<NUM_SUBKEYS;i++)
{
Work.byte.zero = Passwd[(j++)%len];
Work.byte.one = Passwd[(j++)%len];
Work.byte.two = Passwd[(j++)%len];
Work.byte.three = Passwd[(j++)%len];
PA[i] ^= Work.word;
}
null0.word = null1.word = 0;
for (i=0;i<NUM_SUBKEYS;i+=2)
{
BF_En(&null0,&null1);
PA[i] = null0.word;
PA[i+1] = null1.word;
}
for (j=0;j<NUM_S_BOXES;j++)
for (i=0;i<NUM_ENTRIES;i+=2)
{
BF_En(&null0,&null1);
SB[j][i] = null0.word;
SB[j][i+1] = null1.word;
}
}
Work.word = null0.word = null1.word = 0;
Passwd = NULL;
len = 0;
}
void Blowfish::BF_En(Word *x1,Word *x2)
{
Word w1=*x1,w2=*x2;
w1.word ^= PA[0];
w2.word ^= F(w1)^PA[1]; w1.word ^= F(w2)^PA[2];
w2.word ^= F(w1)^PA[3]; w1.word ^= F(w2)^PA[4];
w2.word ^= F(w1)^PA[5]; w1.word ^= F(w2)^PA[6];
w2.word ^= F(w1)^PA[7]; w1.word ^= F(w2)^PA[8];
w2.word ^= F(w1)^PA[9]; w1.word ^= F(w2)^PA[10];
w2.word ^= F(w1)^PA[11]; w1.word ^= F(w2)^PA[12];
w2.word ^= F(w1)^PA[13]; w1.word ^= F(w2)^PA[14];
w2.word ^= F(w1)^PA[15]; w1.word ^= F(w2)^PA[16];
w2.word ^= PA[17];
*x1 = w2;
*x2 = w1;
}
void Blowfish::BF_De(Word *x1,Word *x2)
{
Word w1=*x1,w2=*x2;
w1.word ^= PA[17];
w2.word ^= F(w1)^PA[16]; w1.word ^= F(w2)^PA[15];
w2.word ^= F(w1)^PA[14]; w1.word ^= F(w2)^PA[13];
w2.word ^= F(w1)^PA[12]; w1.word ^= F(w2)^PA[11];
w2.word ^= F(w1)^PA[10]; w1.word ^= F(w2)^PA[9];
w2.word ^= F(w1)^PA[8]; w1.word ^= F(w2)^PA[7];
w2.word ^= F(w1)^PA[6]; w1.word ^= F(w2)^PA[5];
w2.word ^= F(w1)^PA[4]; w1.word ^= F(w2)^PA[3];
w2.word ^= F(w1)^PA[2]; w1.word ^= F(w2)^PA[1];
w2.word ^= PA[0];
*x1 = w2;
*x2 = w1;
}
Blowfish::Blowfish()
{
Reset();
}
Blowfish::~Blowfish()
{
Reset();
}
void Blowfish::Reset()
{
unsigned int i,j;
unsigned int PA_Init[NUM_SUBKEYS] =
{
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
};
unsigned int SB_Init[NUM_S_BOXES][NUM_ENTRIES] =
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
...
...
...
};
for (i=0;i<NUM_SUBKEYS;i++)
PA[i] = PA_Init[i];
for (j=0;j<NUM_S_BOXES;j++)
for (i=0;i<NUM_ENTRIES;i++)
SB[j][i] = SB_Init[j][i];
}
void Blowfish::Set_Passwd(char *Passwd)
{
char New_Passwd[MAX_STRING];
unsigned int i,len;
if (Passwd == NULL)
{
do
{
cout << "\aEnter your password: ";
cin.get(New_Passwd,MAX_STRING,'\n');
len = strlen(New_Passwd);
}
while (len > MAX_PASSWD);
Passwd = New_Passwd;
}
else
len = strlen(Passwd);
Reset();
if (len > 0)
Gen_Subkeys(Passwd);
for (i=0;i<MAX_STRING;i++)
New_Passwd[i] = '\0';
Passwd = NULL;
len = 0;
}
void Blowfish::Encrypt(void *Ptr,unsigned int N_Bytes)
{
unsigned int i;
DWord *Work;
if (N_Bytes%8)
{
cerr << "\aBlowfish requires the input to be a multiple of 8 bytes (64 bits) to work.\n";
return;
}
N_Bytes /= 8;
Work = (DWord *)Ptr;
for (i=0;i<N_Bytes;i++)
{
BF_En(&Work->word0,&Work->word1);
Work++;
}
Work = NULL;
}
void Blowfish::Decrypt(void *Ptr,unsigned int N_Bytes)
{
unsigned int i;
DWord *Work;
if (N_Bytes%8)
{
cerr << "\aBlowfish requires the input to be a multiple of 8 bytes (64 bits) to work.\n";
return;
}
N_Bytes /= 8;
Work = (DWord *)Ptr;
for (i=0;i<N_Bytes;i++)
{
BF_De(&Work->word0,&Work->word1);
Work++;
}
Work = NULL;
}
以下是大端机器上的加密字符串:
11010011 11110110 01100110 10001101 01010011 11000110 00010001 11110110 00011010 11001010 00011111 00100001 10110000 10110100 10110000 11110000 11111100 11000010 00110011 00001111 10011110 01100111 00010101 10000101 00001010 01111110 10000101 00011100 10010010 10111010 10010111 11111001 00111101 01011100 00000010 01010011 11100000 11001101 11111010 00111100 00011101 10001001 01010111 01011010 11100001 10101111 10001100 10111001 00011111111100 10010111011011010001101 11010100 11101111101110110110111110111111111111111111111111110100111010011101100011010001000101000101011101 00110100
这是我通过网络将它发送到小端机器后的加密字符串:
10001101 01100110 11110110 11010011 11110110 00010001 11000110 01010011 00100001 00011111 11001010 00011010 11110000 10110000 10110100 10110000 00001111 00110011 11000010 11111100 10000101 00010101 01100111 10011110 00011100 10000101 01111110 00001010 11111001 10010111 10111010 10010010 01010011 00000010 01011100 00111101 00111100 11111010 11001101 11100000 01011010 01010111 10001001 00011101 10111001 10001100 10101111 11100001 01101110 10010101 10111100 00011111 11010001 11101110 11010100 10001101 01111000 10100111 11111110 10111011 01000001 00110100 01011101 11010001 00010001 10010011 01111100 01011011 01100000 10111100 10011011 10100011
最后,这是字符串需要的内容,以便在小端机器上成功解密它(即这是我在小端机器上加密原始字符串时得到的,而不是大端机器):
10001101 10111011 10110010 10111000 01110001 11000110 00110110 10101110 11000011 11000100 00001010 10011110 11111101 10101000 01110011 10110110 00011001 10000011 11111000 11010001 01101001 00101100 10110001 00010001 11101101 10001011 01101110 01101011 11110001 01101010 00111010 00010110 11101111 01001111 11001100 00011101 01101010 11110000 00110000 01110100 10111010 01000101 01011001 11111001 11011101 01000011 10000110 01000001 11101110 00100001 00111000 00101001 11110011 00001111 01000011 11000000 10110010 10011101 11110000 00000001 10001011 10110101 10010011 01010010 01110100 11100000 10010011 10111101 00111110 00100001 10101111 11010000
我目前正在尝试比较字符串,但找不到模式。
最佳答案
我认为您的问题是您尝试使用字节字符串输入而不以某种方式对其进行字节序更正,以便在不同的字节序平台上进行相同的数学计算:
void Blowfish::Encrypt(void *Ptr,unsigned int N_Bytes)
{
unsigned int i;
DWord *Work;
if (N_Bytes%8)
{
cerr << "\aBlowfish requires the input to be a multiple of 8 bytes (64 bits) to work.\n";
return;
}
N_Bytes /= 8;
Work = (DWord *)Ptr; // NOTE: this won't work on some archs if Ptr isn't properly aligned on a 32b boundary
for (i=0;i<N_Bytes;i++)
{
Work->word0 = ntohl(Work->word0); // necessary to convert byte string to same number on different archs
Work->word1 = ntohl(Work->word1);
BF_En(&Work->word0, &Work->word1);
Work->word0 = htonl(Work->word0); // leave all encryptions in network byte order
Work->word1 = htonl(Work->word1);
Work++;
}
Work = NULL;
}
void Blowfish::Decrypt(void *Ptr,unsigned int N_Bytes)
{
unsigned int i;
DWord *Work;
if (N_Bytes%8)
{
cerr << "\aBlowfish requires the input to be a multiple of 8 bytes (64 bits) to work.\n";
return;
}
N_Bytes /= 8;
Work = (DWord *)Ptr; // NOTE: this won't work on some archs if Ptr isn't properly aligned on a 32b boundary
for (i=0;i<N_Bytes;i++)
{
Work->word0 = ntohl(Work->word0); // necessary to convert byte string to same number on different archs
Work->word1 = ntohl(Work->word1);
BF_De(&Work->word0, &Work->word1);
Work->word0 = htonl(Work->word0); // leave all decryptions in network byte order
Work->word1 = htonl(Work->word0);
Work++;
}
Work = NULL;
}
请注意,使用上述代码,您无需再担心应用程序级别的数据字节顺序问题。相同的输入字节串应该在两个平台上加密/解密为相同的输出字节串。
关于c++ - 跨c套接字的Blowfish加解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28803799/
我似乎找不到差异的来源。我在这个在线解密工具中发现了这种差异 http://www.tools4noobs.com/online_tools/decrypt/ 我有一些加密的 Blowfish 数据,
C++ blowfish 支持加密少于 C# NET BlowfishC++ Blowfish<-- 在 C++ 和 C# 应用程序中,我加密了以下数组 byte response[6] =
我必须实现java密码空间填充。我正在尝试编写支持 Blowfish/CBC/space 模式的 Perl 代码的实现。我在Java Cipher列表中找不到相关模式,仅支持PCK5Padding和N
我正在使用 Blowfish 实现一个简单的密码存储。一切都很好,直到我尝试了几种不同的密码/ key 组合,并遇到了许多解密值仍然是垃圾的情况。 下面是一个演示该问题的独立类。我得到以下输出: 'A
我正在做一个关于图像加密的项目。我们在图像上使用河豚加密。根据 Paul Kocher 的代码 http://www.schneier.com/blowfish-download.html 。主要功能
在将此标记为重复之前,请理解我在 stackoverflow 上找不到任何关于河豚的有用信息。我正在尝试使用 Android Studio 使用河豚加密和解密字符串。我的加密似乎有效。但是当我尝试解密
我正在尝试通过Blowfish解密十六进制编码的字符串。但结果与正确的不同。 String s="a1d0534e4baf9e670bde8670caee8b87" String decKey = "
我今天一整天都在尝试找出如何读取二进制文件并对其进行解密。 在我的文件中,前 4 个字节描述文件格式,后 32 个字节是 header ,使用 Blowfish 加密。 所以我写了这段代码来做到这一点
我用 Blowfish 编码做了一些测试,发现了一些东西。编码后的字符串并不总是与源字符串一样长。有时会更短。 如果我想解码编码字符串,我需要在 openssl 函数中解码的长度: BF_cfb64_
我正在将 C++ TCP 客户端翻译成 C#。该客户端用于使用河豚对数组的 4 个字节进行编码。 C++ Blowfish C# Blowfish(C# NET) C++ BYTE respo
我正在尝试让一个 bowfish 函数用于简单的字符缓冲区。当我尝试解密加密缓冲区并在 EVP_CipherFinal_ex() 调用上失败时,程序失败。 #include #include #i
我正在用 Blowfish 算法加密我的文件,但我似乎对此一无所知。每当我尝试 Encipher() 时,它都会抛出一个异常,提示“无效长度”。我认为当它用 8 进行模数时,长度必须为零,我认为这
许多脚本语言(Python/PHP/等...)包含允许您使用 Blowfish 作为密码单向散列的功能(有时通过扩展)。我正在尝试为 C++ 找到类似的实现,但我遇到的一切都是加密/解密解决方案。 有
我一直在研究在 php 应用程序中保护密码的更好程序。形式上我会使用类似的东西(只是一个例子,不要开枪!): $salt = md5(rand() . md5(rand() . '$%E$%SDRT'
无法解密使用 Blowfish 在 Go 语言中加密的 Java 密文。 加密 import ( "testing" "golang.org/x/crypto/blowfish"
考虑以下执行 Blowfish 加密的方法: import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.spec
我们有一个类,它包装 BouncyCaSTLe(实际上是 Android 的 SpongyCaSTLe)Blowfish,以加密要传输的数据: public class BlowfishOutputS
Blowfish 能够进行强加密,并且可以使用最大 56 字节的 key (448 位 key )。 key 必须是 8 字节的倍数(最多 56)。 我想编写一个示例,它将自动填充和取消填充键的大小。
这是加密和解密消息的基本代码: #include #include #include //gcc cryptage.c -o cryptage -lcrypto int main(){ BF_K
我很难弄清楚如何使用 C# bouncycaSTLe 库来解密河豚 CTR 密文。由于缺少关于如何使用它的 BC 文档,我不知道如何使用它 我广泛搜索但没有在堆栈溢出中找到类似的东西,如果您有一些关于
我是一名优秀的程序员,十分优秀!