如何获取最多19位长BigInteger
并使用以下规则对其进行加密:
我尝试过的事情
取原始数字,用某个键对其进行异或,将其乘以一个因子并将其转换为基数为36的字符串。该因子的目的是扩大范围,因此不会有太多的填充。因子必须介于1到36^16/10^19
之间。这种方法的问题在于:a)它不够“安全”,而b)关闭数字的结果非常相似。
This answer.但是,结果往往太短或太长,之前使用的因子方法在这里不起作用。
答案 0 :(得分:3)
19位略小于64位,因此您只需在ECB模式下使用类似TDEA的8字节分组密码来加密BigInteger值。首先检索BigInteger的默认64位编码,然后用密钥加密,最后基数36对其进行编码。结果将是少于16个字符的几个字符,但您可以随时填充任何值。
请注意,如果您将相同的值加密两次,则会获得相同的结果,因此在这方面,密文会泄漏有关纯文本的一些信息。
答案 1 :(得分:0)
您想要的技术是format perserving encryption。这将允许您将19位数字加密为另一个19位数字。
不幸的是,这种技术的有效版本有点难以实现,事实上,如果选择错误的参数,可能会非常不安全。有图书馆。 This one是开源的。不幸的是它在C ++中,如果它在Windows上运行则不清楚。 Voltage也有一个图书馆,虽然它可能需要花钱,而且我不确定他们支持哪种语言。
答案 2 :(得分:0)
如果您可以将BigInteger
转换为ulong
(9999999999999999999实际上是ulong
),则可以使用以下代码。结果始终是一个固定的16个字符的字符串(十六进制)。
byte[] key = // put your 16-bytes private key here
byte[] iv = Guid.NewGuid().ToByteArray(); // or anything that varies and you can carry
string s = EncryptUInt64(ul, key, iv); // encode
ulong dul = DecryptUInt64(s, key, iv).Value; // decode if possible
public static string EncryptUInt64(ulong ul, byte[] key, byte[] iv)
{
using (MemoryStream output = new MemoryStream())
using (var algo = TripleDES.Create())
{
algo.Padding = PaddingMode.None;
using (CryptoStream stream = new CryptoStream(output, algo.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
byte[] ulb = BitConverter.GetBytes(ul);
stream.Write(ulb, 0, ulb.Length);
}
return BitConverter.ToUInt64(output.ToArray(), 0).ToString("x16");
}
}
public static ulong? DecryptUInt64(string text, byte[] key, byte[] iv)
{
if (text == null)
return null;
ulong ul;
if (!ulong.TryParse(text, NumberStyles.HexNumber, null, out ul))
return null;
using (MemoryStream input = new MemoryStream(BitConverter.GetBytes(ul)))
using (var algo = TripleDES.Create())
{
algo.Padding = PaddingMode.None;
using (CryptoStream stream = new CryptoStream(input, algo.CreateDecryptor(key, iv), CryptoStreamMode.Read))
{
byte[] olb = new byte[8];
try
{
stream.Read(olb, 0, olb.Length);
}
catch
{
return null;
}
return BitConverter.ToUInt64(olb, 0);
}
}
}