gpt4 book ai didi

java - Java 加密与 And .NET 的十六进制生成问题

转载 作者:行者123 更新时间:2023-12-01 12:05:39 25 4
gpt4 key购买 nike

我正在从 Java 和 .NET 系统生成模数和指数,但两者存在差异。我需要像java中的.NET那样的结果。 Java 在模数的十六进制转换中添加两个额外的零,并在指数中删除 1 个零,但 .NET 生成正确。请参阅以下来自 .Net 和 Java 的结果。

<小时/>

如果我使用 toString(16) 那么它会生成以下结果。 toString(16) 不是在模数中添加两个零,而是从指数中删除一个零,其中.NET 在指数中添加一个 0 并从模数中删除两个零,这就是我想要的。

String modlusHexString = publicKey.getModulus().toString(16).toUpperCase();
String exponentHexString = publicKey.getPublicExponent().toString(16).toUpperCase();

模数十六进制转字符串(16): D9B4E023A7CEF604499E184CBA7B7847FE35A824D15FF902EADB952FB54620158A564EFDDB0A66A7647CBDB339359BF6756F5851A73CC1D248 59A064DD7AE30B2330F965C54682B10E886D35FE005F42B056C7ABF64D3F6D592AEDC0234417507A0A1432E51C7867E3ACC4867A1AE03EF9E62050180882B18771D57 03C8BADCB3AC767CD1A1C0F9344F10B8C82EF5D0ACA4422512EA3ECCB5B71097BDEDAD9BBBE11697D1E61814CF3BBDEB48BDC2C95AA10DFC3F7F794E307D49B5455F928A9BB3ED2F2 8D6E2974238EFB2D9A822EC1832177CB988206204DF1D9DB7D291E2816576BEBD669184894B526F0B5D10C7D19FA67E79DADDF97D4A3082D4812A27B

指数十六进制转字符串(16): 10001

<小时/>

我尝试了下面的方法也将模数和指数的 BigInteger 转换为十六进制,但没有运气-

static String toHex(byte[] ba) {
StringBuilder hex = new StringBuilder(ba.length * 2);
for (byte b : ba) {
hex.append(String.format("%02x", b, 0xff));
}
return hex.toString().toUpperCase();
}

模数十六进制: 00D9B4E023A7CEF604499E184CBA7B7847FE35A824D15FF902EADB952FB54620158A564EFDDB0A66A7647CBDB339359BF6756F5851A73CC1D24859A 064DD7AE30B2330F965C54682B10E886D35FE005F42B056C7ABF64D3F6D592AEDC0234417507A0A1432E51C7867E3ACC4867A1AE03EF9E62050180882B18771D5703C 8BADCB3AC767CD1A1C0F9344F10B8C82EF5D0ACA4422512EA3ECCB5B71097BDEDAD9BBBE11697D1E61814CF3BBDEB48BDC2C95AA10DFC3F7F794E307D49B5455F928A9BB3ED2F28D6 E2974238EFB2D9A822EC1832177CB988206204DF1D9DB7D291E2816576BEBD669184894B526F0B5D10C7D19FA67E79DADDF97D4A3082D4812A27B

指数: 010001

<小时/>

以下是 .NET 生成的公钥模数和指数的十六进制,这是正确的

  • .NET

十六进制模数:F86020AFD75A03911BE8818BCB506B5DAC2760C68BB46F2A53E10E3E0972A7FFFFF71EAC0E0D73E8FDB4C332C759E781E54C0F1F4637656E6E995873B9580027F496 06811C7B5DB458C1BAC3E3D6EB7B77BFE1E55A822F23797E4CB27C7BD88C1B782AEF5235DAE55B937ABB0FFD30AF64F8D69DA07946441D9E4704FA98BD026E00A92851FABC8 AB347AB75615ACC8A7CCFDE56B0797DDB70FCA1F28F23F86548AABE6DD89B5CC859BC6352D077F765AACF15695215850A8D7E1F9DF187AE0EF1934E096B739E884757F810B33 20EFA72BBE2A957CE465E2010A5FD9C96A5F6456658D3BA0DF51B472AFEBEF31C3609B58C6A03C671DA33650039822465179

指数: 010001

最佳答案

您遇到的问题是由方法 BigInteger.toString(int radix)BigInteger.toByteArray() 的行为造成的。

当您调用BigInteger.toString(int radix)方法时,它仅返回数字的有效数字。因此,例如,如果该值应为 05ABFF,则它仅返回 5ABFF。当基数为 10 时,这是很自然的(我们不希望大整数 13 被转换为类似 013 的东西),但是当基数是 16,因为您期望输出具有偶数长度,每个字节恰好有两个字符。但事实并非如此。

但是当您调用自己的 toHex() 方法时,它基于从 BigInteger.toByteArray() 返回的值。在这里你还有另一个问题。此方法始终返回表示数字所需的字节数,包括符号位。现在考虑数字0xD9B4E023。如果它被视为整数,那么它实际上是一个负数,但如果它被 BigInt 视为正数,则需要一个额外的字节来表示符号。因此,在您的方法中,附加字节会转换为 00

我可以想到两种可能的解决方案:

static String toHex(byte[] ba) {
StringBuilder hex = new StringBuilder(ba.length * 2);
boolean skipZeroBytes = true;
for (byte b : ba) {
// As soon as we hit the first non-zero byte, we stop skipping bytes
if (b != 0) {
skipZeroBytes = false;
}
// If the current byte is zero, and we are in skipping mode, skip
if (skipZeroBytes) {
continue;
}
hex.append(String.format("%02X", b, 0xff));
}
if (skipZeroBytes) {
// If we are still in skipping mode, it means all the bytes in the
// array were zero and we skipped them all. So just return the
// representation of a zero.
return "00";
} else {
return hex.toString();
}
}

我们在这里所做的是跳过所有初始零字节,直到我们到达第一个非零字节,然后才开始解释它。小提示:使用格式 %02X 和大写的 X 可以为您提供大写的十六进制数字,并且无需稍后调用 toUpperCase()

另一种更简单的方法是将缺少的零添加到 BigInteger.toString(int radix) 的结果中:

static String toHex2(BigInteger bi) {
String hex = bi.toString(16).toUpperCase();
if (hex.length() % 2 == 1) {
return "0" + hex;
} else {
return hex;
}
}

关于java - Java 加密与 And .NET 的十六进制生成问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27641519/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com