【发布时间】:2018-05-11 17:46:36
【问题描述】:
我想用 SPECK 算法加密一个字符串。我们有一个密码,我们得到它的哈希值,从那个哈希值中得到一个 128 位的密钥 - 哈希算法是 SHA256。 在解密中我得到无效的字符串 - 块大小:128 和密钥大小 128,第 32 轮
public static void SpeckEnc(byte[] sha,String message){
byte[] data=message.getBytes();
byte[] newdata;
byte[] lastblock=new byte[16];
byte[] key=new byte[16];
int tool=data.length/16;
final int baghi=data.length%16;
for(int I = 0; I < 16; I++)
key[I] = (byte) (sha[I] ^ sha[I + 16]);
if(baghi!=0){
int toollast=data.length - tool*16;
for(int ba=0;ba<16;ba++){
if(ba<toollast)
lastblock[ba]=data[tool*16+ba];
else
lastblock[ba]=0;
}
tool++;
newdata=new byte[tool*16];
System.arraycopy(data,0,newdata,0,(tool-1)*16);
System.arraycopy(lastblock,0,newdata,(tool-1)*16,16);
}else
newdata=data;
byte[] c=new byte[newdata.length];
byte[] k1 = Arrays.copyOfRange(key, 0, 8);
byte[] k2 = Arrays.copyOfRange(key, 8, 16);
byte[] pofd;
for(int i=0;i<tool;i++){
pofd=Arrays.copyOfRange(newdata,i*16,i*16+16);
System.out.print(pofd[0]+" ");
pofd=enc(pofd,k1,k2);
System.out.print(pofd[0]+" |\n");
System.arraycopy( pofd,0,c,i*16,16);
}
String encoded = Base64.getEncoder().encodeToString(c);}
主要加密功能:
public static byte[] enc(byte[] piecedata,byte[] k1,byte[] k2){
byte[] result=new byte[16];
byte[] pt1=new byte[8];
byte[] pt2=new byte[8];
for(int si = 0; si < 32; si++) {
k1=generateKey(k1,k2,si);
k2=generatekey2(k1,k2);
pt1=circularBitShiftingRight(pt1,8);
pt1=plus(pt1,pt2);
for(int i=0;i<8;i++)
pt1[i]=(byte) (pt1[i]^k2[i]);
pt2=circularBitShiftingLeft(pt2,3);
for(int i=0;i<8;i++)
pt2[i]=(byte) (pt1[i]^pt2[i]);
}
System.arraycopy(pt1,0,result,0,8);
System.arraycopy(pt2,0,result,8,8);
return result;
}
解密部分:
public static void SpeckDec(byte[] sha,String base64message){
byte[] decodedString = Base64.getDecoder().decode(base64message.getBytes());
byte[] data=new byte[decodedString.length];
byte[] keys=new byte[256];
byte[] key=new byte[16];
byte[] pofd,p;
final int tool=decodedString.length/16;
for(int I = 0; I < 16; I++)
key[I] = (byte) (sha[I] ^ sha[I + 16]);
byte[] k1 = Arrays.copyOfRange(key, 0, 8);
byte[] k2 = Arrays.copyOfRange(key, 8, 16);
for (int i=0;i<32;i++)
{
k1=generateKey(k1,k2,i);
k2=generatekey2(k1,k2);
System.arraycopy(k2,0,keys,i*8,8);
}
for(int i=0;i<tool ;i++){
pofd=Arrays.copyOfRange(decodedString,i*16,i*16+16);
p=dec(pofd,keys);
System.arraycopy(p, 0, data, i*16, 16);
}}
主解密函数:
public static byte[] dec(byte[] pieceofdata,byte[] keys){
byte[] result=new byte[16];
byte[] key;
byte[] ct1=new byte[8];
byte[] ct2=new byte[8];
int m;
for(int i=0;i<32;i++){
m=256-((i+1)*8);
key=Arrays.copyOfRange(keys,m,m+8);
for(int j=0;j<8;j++)
ct2[j]=(byte) (ct1[j]^ct2[j]);
ct2=circularBitShiftingRight(ct2,3);
for(int j=0;j<8;j++)
ct1[j]=(byte) (ct1[j]^key[j]);
for(int j=0;j<8;j++)
ct1[j]=(byte) (ct1[j]-ct2[j]);
ct1=circularBitShiftingLeft(ct1,8);
}
System.arraycopy(ct1, 0, result, 0, 8);
System.arraycopy(ct2, 0, result, 8, 8);
return result;}
生成密钥函数:
public static byte[] generateKey(byte[] k1,byte[] k2,int x){
byte[] a=circularBitShiftingRight(k1,8);
a=plus(a,k2);
for(int i=0;i<8;i++)
a[i]=(byte) (a[i]^x);
return a;}
public static byte[] generatekey2(byte[] k1,byte[] k2){
byte[] t =circularBitShiftingLeft(k2,3);
for(int i=0;i<8;i++)
t[i]=(byte) (t[i]^k1[i]);
return t;}
加函数:
public static byte[] plus(byte[] a,byte[] b){
byte[] s=new byte[8];
for(int i=0;i<8;i++){
s[i]=(byte) (a[i]+b[i]);
}
return s;}
您可以阅读 SPECK 算法的详细信息:
【问题讨论】:
-
1.为什么要使用 SPECK 而不是 AES? 2. 你为什么要相信 NSA,那些提供了具有潜在后门的 CSPRNG Dual_EC_DRBG 的家伙。请参阅Opposition to ISO approval 3。如果您正在编写一个实现,它很可能会受到诸如计时之类的攻击。 4. SHA-256 不是安全密钥派生算法,PBKDF2 或 Argon2 推荐 KDF。
-
@zaph:你是谁告诉人们他们应该和不应该信任谁?
-
编写自己的加密/解密代码总是一个错误。除非你有该领域的经验,否则你会让自己容易受到攻击。找一个知名的、经过研究的库来实现它。
-
@JamesKPolk 我不是,如果您愿意,请忽略。但我写的是“你为什么要相信国家安全局”,这是一个问题,对吗?到目前为止,同行评审似乎确实很少。
-
我必须使用轻量级算法才能在弱设备中使用。 AES 很复杂。并且不是在 java 中实现 SPECK 的库
标签: java android encryption sha