- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是一名学生,正在做一个小项目 - DES 实现。
我之前对将 64 位 key 转换为 56 位 key 有疑问,多亏了这里收到的一些指导,我可以成功地做到这一点。
我将我的实现分为 key 生成阶段(我为 16 轮中的每一轮生成一个新 key )和加密阶段。
但是,我无法生成正确的 key 。
我使用“abcdefgh”作为键手动做了一个例子,但我无法在我的程序中重现结果。
DES key 生成阶段包括:
leftkey28[4]
(最后 4 位为 0) & rightkey28[4]
(前 4 位为 0)Round#2 Byte#2
在我的输出中。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author krish 2nd Aug, 2011
*/
class DES {
final static int KEY_LENGTH = 8; // 8 byte key, 64 bits
final static int BLOCK_SIZE = 8; // 8 byte blocks, 64 bits
final static int NUM_ROUNDS = 16; // 16 rounds per block
// =======================================================================
// FOR KEY TRANSFORMATION
int[] compressionPermutation = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21,
10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47,
55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36,
29, 32 };
// int[] keyShiftValue = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
// ---
// don't need this
// =======================================================================
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter an 8 char key: ");
String inputKey, inputMsg;
char[] inputArray;
byte[] key64 = new byte[8];
byte[] key56 = new byte[7];
int counter;
try {
// get key, key length() >= 8 chars
// inputKey = br.readLine();// uncomment later!!$$$$$$$
inputKey = "abcdefgh";
System.out.println(inputKey);
if (inputKey.length() < 8) {
System.out.println("Key < 8 B. Exiting. . .");
System.exit(1);
}
// java char has 16 bits instead of 8 bits as in C,
// so convert it to 8 bit char by getting lower order byte &
// discarding higher order byte; &
// consider only first 8 chars even if input > 8
inputArray = inputKey.toCharArray();
for (counter = 0; counter < 8; counter++)
key64[counter] = (byte) inputArray[counter];
// converting 64bit key to 56 bit key
for (counter = 0; counter < KEY_LENGTH - 1; counter++) {
key64[counter] = (byte) (key64[counter] >>> 1);
key64[counter] = (byte) (key64[counter] << 1);
}
for (counter = 0; counter < KEY_LENGTH - 1; counter++) {
key56[counter] = (byte) (key64[counter] << counter);
key56[counter] = (byte) (key56[counter] | (key64[counter + 1] >>> (KEY_LENGTH - 1 - counter)));
}
/*
* Conversion from 64 to 56 bit testing code
*
* System.out.println("64 to 56 test:"); System.out.println(new
* String(key56)); System.out.println(); for (int counter1 = 0;
* counter1 < 7; counter1++) { for (int counter2 = 7; counter2 >= 0;
* counter2--) { System.out.println(key56[counter1] & (1 <<
* counter2)); } System.out.println(); }
*/
// end of obtaining 56bit key
// KEY GENERATION PHASE
// DS USED - compressionPermutation
byte[] leftKey28 = new byte[4];
byte[] rightKey28 = new byte[4];
byte circularBit;
byte[][] newKey56 = new byte[16][7];
// new 56 bit key for the first round, then loop for other rounds
leftKey28[0] = key56[0];
leftKey28[1] = key56[1];
leftKey28[2] = key56[2];
leftKey28[3] = (byte) (key56[3] & 11110000);
// rightKey28[0] = (byte) (key56[3] & 00001111);
// prob here, doesnt work as given above??
rightKey28[0] = (byte) (key56[3] - leftKey28[3]);
rightKey28[1] = key56[4];
rightKey28[2] = key56[5];
rightKey28[3] = key56[6];
/*
* // printing starts here System.out.print("1 Byte # 0" + " ");
* for (int counter2 = 7; counter2 >= 0; counter2--) {
* System.out.print(leftKey28[0] & (1 << counter2));
* System.out.print(", "); } System.out.println(); // printing ends
* here
*/
circularBit = (byte) (leftKey28[0] & (1 << 7));
leftKey28[0] = (byte) (leftKey28[0] << 1);
leftKey28[0] = (byte) (leftKey28[0] | ((((int) leftKey28[1]) & 0xff) >>> 7));
leftKey28[1] = (byte) (leftKey28[1] << 1);
leftKey28[1] = (byte) (leftKey28[1] | ((((int) leftKey28[2]) & 0xff) >>> 7));
leftKey28[2] = (byte) (leftKey28[2] << 1);
leftKey28[2] = (byte) (leftKey28[2] | ((((int) leftKey28[3]) & 0xff) >>> 7));
leftKey28[3] = (byte) (leftKey28[3] << 1);
leftKey28[3] = (byte) (leftKey28[3] | ((((int) circularBit) & 0xff) >>> 3));
circularBit = (byte) (rightKey28[0] & (1 << 3));
circularBit <<= 4;
rightKey28[0] = (byte) (rightKey28[0] << 1);
rightKey28[0] = (byte) (rightKey28[0] | ((((int) rightKey28[1]) & 0xff) >>> 7));
rightKey28[1] = (byte) (rightKey28[1] << 1);
rightKey28[1] = (byte) (rightKey28[1] | ((((int) rightKey28[2]) & 0xff) >>> 7));
rightKey28[2] = (byte) (rightKey28[2] << 1);
rightKey28[2] = (byte) (rightKey28[2] | ((((int) rightKey28[3]) & 0xff) >>> 7));
rightKey28[3] = (byte) (rightKey28[3] << 1);
rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 3));
newKey56[0][0] = leftKey28[0];
newKey56[0][1] = leftKey28[1];
newKey56[0][2] = leftKey28[2];
newKey56[0][3] = (byte) (leftKey28[3] | rightKey28[0]);
newKey56[0][4] = rightKey28[1];
newKey56[0][5] = rightKey28[2];
newKey56[0][6] = rightKey28[3];
// we have a new left circular shifted key in newKey56
// done testing for newkey56[0] // left and right testing code
for (int counter1 = 0; counter1 < 7; counter1++) {
System.out.print("Round#0 Byte#" + counter1 + " ");
for (int counter2 = 7; counter2 >= 0; counter2--) {
if (counter2 == 3)
System.out.print(" ");
if ((newKey56[0][counter1] & (1 << counter2)) > 0) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.println();
}
// left and right testing code ends here
// for round 1 to 15: left circular shift each 28 bit block by 1{
for (int round = 1; round < NUM_ROUNDS; round++) {
// for the first round, then loop for other rounds
leftKey28[0] = newKey56[round - 1][0];
leftKey28[1] = newKey56[round - 1][1];
leftKey28[2] = newKey56[round - 1][2];
leftKey28[3] = (byte) (newKey56[round - 1][3] & 11110000);
// rightKey28[0] = (byte) (newKey56[round - 1][3] & 00001111);
rightKey28[0] = (byte) (newKey56[round - 1][3] - leftKey28[3]);
rightKey28[1] = newKey56[round - 1][4];
rightKey28[2] = newKey56[round - 1][5];
rightKey28[3] = newKey56[round - 1][6];
// if (round == 1 || round == 8 || round == 15) {
// left circular shift by 1
circularBit = (byte) (leftKey28[0] & (1 << 7));
leftKey28[0] <<= 1;
leftKey28[0] |= ((((int) leftKey28[1]) & 0xff) >>> 7);
leftKey28[1] <<= 1;
leftKey28[1] |= ((((int) leftKey28[2]) & 0xff) >>> 7);
// ////////////////////////error here ////////////////////////////
leftKey28[2] <<= 1;
leftKey28[2] |= ((((int) leftKey28[3]) & 0xff) >>> 7);
// ////////////////////////error here //////////////////////////
leftKey28[3] <<= 1;
leftKey28[3] |= ((((int) circularBit) & 0xff) >>> 3);
circularBit = (byte) (rightKey28[0] & (1 << 3));
circularBit <<= 4;
// //////////////////////////////////////////////////
rightKey28[0] = (byte) (rightKey28[0] << 1);
rightKey28[0] &= 00001111;
rightKey28[0] = (byte) (rightKey28[0] | ((((int) rightKey28[1]) & 0xff) >>> 7));
// //////////////////////////////////////////////////
rightKey28[1] = (byte) (rightKey28[1] << 1);
rightKey28[1] = (byte) (rightKey28[1] | ((((int) rightKey28[2]) & 0xff) >>> 7));
rightKey28[2] = (byte) (rightKey28[2] << 1);
rightKey28[2] = (byte) (rightKey28[2] | ((((int) rightKey28[3]) & 0xff) >>> 7));
rightKey28[3] = (byte) (rightKey28[3] << 1);
rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 7));
// } else {
// // left circular shift by 2
// }
newKey56[round][0] = leftKey28[0];
newKey56[round][1] = leftKey28[1];
newKey56[round][2] = leftKey28[2];
newKey56[round][3] = (byte) (leftKey28[3] | rightKey28[0]);
newKey56[round][4] = rightKey28[1];
newKey56[round][5] = rightKey28[2];
newKey56[round][6] = rightKey28[3];
// testing code for all keys for rounds 1 to 15
System.out.println();
for (int counter1 = 0; counter1 < 7; counter1++) {
System.out.print("Round#" + round + " Byte#" + counter1
+ " ");
for (int counter2 = 7; counter2 >= 0; counter2--) {
if (counter2 == 3)
System.out.print(" ");
if ((newKey56[round][counter1] & (1 << counter2)) > 0) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.println();
}
if (round == 2)
break;
// testing code ends
}// for loop ends
/*
* // newKey56 testing code
* System.out.println("new56key testing here"); for (counter = 0;
* counter < NUM_ROUNDS; counter++) { System.out.println(new
* String(newKey56[counter])); System.out.println();
*
* for (int counter1 = 0; counter1 < 7; counter1++) {
* System.out.print("Round # " + counter + " Byte # " + counter1 +
* " "); for (int counter2 = 7; counter2 >= 0; counter2--) {
* System.out.print(newKey56[counter][counter1] & (1 << counter2));
* System.out.print(", "); } System.out.println(); } }
*/
// DO KEY COMPRESSION ROUTINE HERE
} catch (Exception e) {
e.printStackTrace();
}
}
}
Enter an 8 char key:
abcdefgh
Round#0 Byte#0 1100 0001
Round#0 Byte#1 1000 1011
Round#0 Byte#2 0001 0110
Round#0 Byte#3 0100 1100
Round#0 Byte#4 1001 1001
Round#0 Byte#5 1011 0011
Round#0 Byte#6 0110 1000
Round#1 Byte#0 1000 0011
Round#1 Byte#1 0001 0110
Round#1 Byte#2 0010 1100
Round#1 Byte#3 1001 1001
Round#1 Byte#4 0011 0011
Round#1 Byte#5 0110 0110
Round#1 Byte#6 1101 0001
Round#2 Byte#0 0000 0110
Round#2 Byte#1 0010 1100
Round#2 Byte#2 0101 1000 //error here => 0101 1001
Round#2 Byte#3 0011 0000 //error here => 0011 0010
Round#2 Byte#4 0110 0110
Round#2 Byte#5 1100 1101
Round#2 Byte#6 1010 0011
最佳答案
DES 的约定是假装你有 64 位 key (8 个字节),但如果你真的,呃,迂腐,你用前 7 位的奇偶校验破坏每个字节的第 8 位。
我只玩过 Java,而且我看到 Java(Sun/Oracle JRE)不会费心检查奇偶校验。它只是忽略每个字节的第 8 位。
也许是 DESEngine
在 BouncyCaSTLe 中会对您有所帮助。 generateWorkingKey()
方法看起来很有趣:
http://www.bouncycastle.org/viewcvs/viewcvs.cgi/java/crypto/src/org/bouncycastle/crypto/engines/DESEngine.java?view=markup
关于java - Java 中的 DES 实现 : Error during Key Generation Phase,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7045756/
我正在尝试使用 DES API 来实现 3Des,如下所示: des(input, output, key, mode) 其中输入、输出和 key 各为 8 个字节,模式标识加密和解密类型。我想知道是
有人比较这些加密算法的优缺点吗? 最佳答案 使用 AES。 更多详细信息: DES 是七十年代的旧“数据加密标准”。它的 key 大小对于适当的安全性而言太短(56 个有效位;这可以被暴力破解,如 m
我收到了来自Java的加密字符串,我可以看到Java加密的源代码。我用C#编写了解密代码。但总是在“FlushFinalBlock”处报错。错误消息:“System.Security.Cryptogr
我应该使用加密 DES-EDE3-CBC。这是否意味着它是密码 block 链接模式下的 Triple DES? 最佳答案 是的。 EDE 部分告诉您使用 3DES 的特定变体(无论如何,每个人都默认
有没有人一起比较这些加密算法的优缺点? 最佳答案 使用 AES。 更多细节: DES 是七十年代的旧“数据加密标准”。它的 key 大小对于适当的安全性来说太短了(56 位有效位;这可以被强制执行,正
我在整个网络上寻找这个问题,但找不到明确的答案: 我有一些使用 DESCryptoServiceProvider(Mode = CRC,Padding = none)的 C# 代码,并且我正在使用 o
嗨,大家好,我有 java 代码,它为我生成三重加密代码,现在我尝试使用 crypto-js 在 javascript 上使用它,但这两个代码提供了不同的 key ,我不知道为什么以及如何获得相同的
我需要在我的 Erlang/OTP Web 服务器和 JavaScript 之间传送加密数据。我已经 checkout Crypto-js.js Library 。我想使用 DES 加密我的数据 在
我发现了一个问题,Elephantik 的答案基本上回答了我的问题: DES Initialization Vector in C# 我有一个使用 DES.EXE 命令行工具加密的文件。我可以使用以下
我正在努力让 Java 代码输出与 C# 代码相同的 Byte[]。 C# 代码: using System; using System.IO; using System.Security.Crypt
我从第三方公司收到了一些 DES 加密的东西。我无法用 ruby 解密它。但它适用于我的 java 代码。 这里是java代码: public class Main { public static v
它似乎混淆了 Triple-DES(>128 位)和普通 DES(64 位)。我正在尝试使用 Java 1.5 使用 Triple DES(或 DESede)加密 Derby 数据库 我找到了这个 d
我遇到了编码问题。我想在 HTML 文件中添加法语口音。 我在 Ubuntu 上,我的编辑器是 SciTE。 这是一个 Ruby on Rails 程序。 ActionView::WrongEncod
这个问题已经有答案了: Error parsing XHTML: The content of elements must consist of well-formed character data
我需要加密 ISO 8583消息...这里的问题是消息比 key 长。我需要有人帮我加密这个字符串。 例如:我的字符串中有 300 个字符;我应该单独加密每 16 个字符然后连接它们,因为我的主 ke
我想知道在下面的代码中是否添加了 PKCS#5 填充?如果不是如何添加? $message = "insert plaintext message here"; $iv = pack('H*', '
我已经使用内置库在 Java 中编码了 DES,但我没有得到正确的加密结果。请解释一下我在哪里犯了错误 import javax.crypto.Cipher; import javax.crypto.
在下面,您将看到一个简单的 Java Card 小程序,它被编写为使用不同的 DES 和 3DES 算法加密和解密数据。 这些是支持的命令: 00 C0 00 00 | key 长度 | KeyVal
我在我的应用程序中使用 DES-ECB + base64 加密。这就是我称之为“Crypto”的类的代码 public class Crypto { public static string
我创建了一个 Android 应用程序,它从安装在智能手机上的传感器读取数据,并将这些数据以 JSON 格式发送到应用程序服务器。 我将服务器和 Android 应用程序配置为通过 https 协议(
我是一名优秀的程序员,十分优秀!