我正在尝试接受密码学并且一直在尝试这个练习
编写程序(最好是Java)来生成一次性填充,这是一个相对较大的文件 随机数据(比如1 MB)。该程序还应该能够根据文件加密/解密文件 生成一次性垫。
提示:使用以下测试向量检查您的程序是否正确加密。
明文(ASCII):每一朵云都有一线希望
OTP(HEX):6dc72fc595e35dcd38c05dca2a0d2dbd8e2df20b129b2cfa29ad17972922a2
密文(HEX):28b14ab7ecc33ea157b539ea426c5e9def0d81627eed498809c17ef9404cc5
我尝试使用随机数生成器生成一次性打击垫,因为我需要将它们转换为HEX格式。而且我很确定我很困惑或者没有以正确的方式解决它
public static void oneTimePad()
{
Random ran = new Random();
String s = "0123456789ABCDEF";
for(int i = 0; i < 100; i++)
{
System.out.print(s.charAt(ran.nextInt(s.length())));
}
}
以上将是我的一次性填充,我想知道如何使用一次性密码并解密它来实现加密。
答案 0 :(得分:8)
这里有一个完整的工作示例:
// convert secret text to byte array
final byte[] secret = "secret".getBytes()
final byte[] encoded = new byte[secret.length];
final byte[] decoded = new byte[secret.length];
// Generate random key (has to be exchanged)
final byte[] key = new byte[secret.length];
new SecureRandom().nextBytes(key);
// Encrypt
for (int i = 0; i < secret.length; i++) {
encoded[i] = (byte) (secret[i] ^ key[i]);
}
// Decrypt
for (int i = 0; i < encoded.length; i++) {
decoded[i] = (byte) (encoded[i] ^ key[i]);
}
assertTrue(Arrays.equals(secret, decoded));
答案 1 :(得分:3)
对于一次性填充,您需要一个字节数组,而不是十六进制数组。十六进制仅用于显示数据(我们往往难以读取位)。您可以使用Apache Commons库(编解码器包)从字节数组创建十六进制,如果要将测试向量从十六进制解码为字节,则可以返回。
您应该使用安全随机数生成器,而不是Random
。所以请改用new SecureRandom()
。要生成随机数据,首先要创建一个字节数组,然后在随机数生成器上调用nextBytes()
。不需要生成整数。
答案 2 :(得分:2)
这里首先是一个名为HOTP的OTP算法,它是一个标准的RFC。几乎所有其他OTP都是适当的,我们不知道那些算法。
http://tools.ietf.org/html/rfc4226
你可以用一些java代码来学习它是如何完成的。其次,如果要进行加密,请不要使用Random。随机对于psuedo随机很好,但如果你真的想要一个好的随机数据源,你需要采用SecureRandom。这是一个更好的随机数源,适用于cryto算法。
将东西转换为Hex可以轻松使用
http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigInteger.html#toString(int)
或任何变种Long.toString(value,radix),Integer.toString(value,radix)或Byte.toString(value,radix)。
byte[] bytes = ...;
for( int i = 0; i < bytes.length; i++ ) {
System.out.println( Integer.toString( bytes[i], 16 );
}
答案 3 :(得分:0)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace one_time_pad
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(" TRYING\n");
Console.WriteLine("Enter : ");
int input= int.Parse( Console.ReadLine());
//random num generation
Random rnd = new Random();
int random = rnd.Next(1,10);
//binary conversion
string binary = Convert.ToString(random,2);
string inbinary = Convert.ToString(input,2);
Console.WriteLine("Data : " +input +" Binary : " + inbinary);
Console.WriteLine(" Key : " +random + " Binary : " + binary);
// taking xor
int Ghul = input ^ random;
//binary conversion
string intcon = Convert.ToString(Ghul,2);
Console.WriteLine("Encrypted : " + intcon);
Console.WriteLine(":)");
Console.Read();
}
}
}
答案 4 :(得分:0)
https://en.wikipedia.org/wiki/One-time_pad
public static String crypt(String string, String keyString) {
// convert secret text to byte array
byte[] bytes = string != null ? string.getBytes() : new byte[0];
int size = bytes != null ? bytes.length : 0;
final byte[] encoded = new byte[size];
final byte[] key = keyString != null ? keyString.getBytes() : new byte[0];
// loop on input bytes
for (int i = 0; i < size; i++) {
// shift key index
// (we assume key can be smaller or equal if larger then adjust)
int keyi = i >= keySize ? size % (keySize-1) : i;
// pad
encoded[i] = (byte) (bytes[i] ^ key[keyi]);
}
return new String(encoded);
}
public static void test(String string, String keyString) {
String encrypt = crypt(string, keyString);
String decrypt = crypt(encrypt, keyString);
assert(string.equals(decrypt));
}
test("test","1234");
test("test","123");
PS。你可以通过拉取字符串来重构方法并用字节替换
public static byte[] crypt(byte[] bytes, byte[] key) {
int size = bytes != null ? bytes.length : 0;
final byte[] encoded = new byte[size];
int keySize = key != null ? key.length : 0;
// loop on input bytes
for (int i = 0; i < size; i++) {
// shift key index (assuming key <= bytes)
int keyi = i >= keySize ? size % (keySize-1) : i;
// pad
encoded[i] = (byte) (bytes[i] ^ key[keyi]);
}
return encoded;
}
答案 5 :(得分:0)
<dependency>
<groupId>work.eddiejamsession</groupId>
<artifactId>jam-one-time-pad</artifactId>
<version>0.67</version>
</dependency>
JamOneTimePad pad = new JamOneTimePad();
String heyEncrypted = pad.encrypt("hey"); //encodes additionally in base64 for url safety
String heyDecrypted = pad.decrypt(heyEncrypted);
System.out.println(heyDecrypted.equals("hey"));
Output: true