У меня есть код Java, в который я отправляю пакет с зашифрованным ключом:
protected void write()
{
writeC(0x00);
writeD(_sessionId);
writeD(PROTOCOL_VERSION);
writeB(_publicKey); --- > scrambled key
writeB(UNKNOWN_GG);
writeB(_blowfishKey);
writeC(0x00);
}
В моем Java-коде я могу правильно расшифровать зашифрованный ключ, используя следующий метод расшифровки:
public void run()
{
final LoginClient client = getClient();
byte[] decrypted = null;
try
{
final Cipher rsaCipher = Cipher.getInstance("RSA/ECB/nopadding");
rsaCipher.init(Cipher.DECRYPT_MODE, client.getRSAPrivateKey());
decrypted = rsaCipher.doFinal(_raw, 0x00, 0x80);
}
catch (GeneralSecurityException e)
{
LOGGER.error("Failed to generate a cipher.", e);
client.close(LoginFail.REASON_ACCESS_FAILED);
return;
}
try
{
final String user = new String(decrypted, 0x5E, 14).trim().toLowerCase();
final String password = new String(decrypted, 0x6C, 16).trim();
LoginController.getInstance().retrieveAccountInfo(client, user, password);
}
catch (Exception e)
{
LOGGER.error("Failed to decrypt user/password.", e);
client.close(LoginFail.REASON_ACCESS_FAILED);
}
}
В Java расшифровка работает правильно со следующими входными данными:
Зашифрованный ключ:
[124, 168, 24, 242, 228, 213, 212, 54, 235, 100, 160, 114, 163, 61, 75, 218, 182, 245, 166, 34, 214, 132, 15, 71, 135, 194, 141, 227, 38, 1, 217, 145, 203, 135, 209, 137, 111, 33, 54, 34, 57, 0, 189, 243, 199, 219, 109, 56, 15, 225, 143, 59, 176, 108, 76, 204, 232, 133, 216, 126, 70, 30, 115, 74, 25, 0, 133, 38, 128, 16, 28, 183, 155, 24, 188, 86, 117, 191, 135, 36, 211, 165, 104, 217, 6, 182, 164, 136, 101, 215, 42, 113, 111, 55, 208, 207, 105, 35, 182, 47, 241, 107, 139, 215, 213, 249, 43, 125, 219, 34, 53, 103, 250, 92, 154, 128, 75, 189, 168, 128, 229, 6, 239, 177, 101, 126, 218, 75]
Закрытый ключ Java:
SunRsaSign RSA private CRT key, 1024 bits
params: null
modulus: 91851415039980683673835443907833548355613725060429787547716446884026400945844827342368025805543719063805785824109075005634172820422680533076648130137521254244221874431195148950936257983839718841574094615493929797376689026996944801887459231860502077721291214210394902757594184173778070286729141127782416296193
private exponent: 6487635995240407475566233880851450254636860602479965310563184653343274943593934811905055029279061836006484620592961353145255138101173202734513392349460393317252650745961877082056763589015732603463063131507792018004450541681668317154023863374611531824451608552071840032997073721859882730955156029598795586149
Chave privada (formato Go):
&rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: big.NewInt(0).SetBytes(new byte[] {0, -126, -52, -2, 101, -128, 16, 28, -73, -101, 24, -68, 86, 117, 15, -21, 104, 31, -91, 104, -39, 6, -74, -92, -120, 101, -41, 42, 113, 111, 55, -48, -49, 105, 35, -74, 47, -15, 107, -117, -41, -43, -7, 43, 125, -37, 34, 53, 103, -6, 92, -102, -128, 75, -67, -88, -128, -27, 6, -17, -79, 101, 126, -38, 75, 101, -88, -99, -44, 100, -59, -56, -127, 112, 124, 28, 36, -42, 25, 0, -123, 38, 80, -50, -5, -48, 50, -85, -49, -30, 21, -89, -110, 73, 54, 9, 94, -94, -92, 103, -90, -98, 74, -67, -11, -20, -7, -106, -114, 28, -7, 88, 95, -11, -67, 21, -69, -5, -47, -28, 76, 13, -125, 55, -49, 35, 96, -87, 1, }),
E: 65537,
},
D: big.NewInt(0).SetBytes(new byte[] {9, 61, 27, 118, -27, -35, -67, 121, -122, 125, -17, -57, -105, -117, 33, 80, -128, 115, -71, 125, 34, -55, 65, -61, -44, -107, -89, 12, -50, 19, 62, 47, 120, 56, -86, -124, -90, 99, -73, 67, -18, 124, 36, 3, 70, -72, 26, -41, -106, 74, 118, 43, 59, -82, 80, -71, -111, -13, -76, 120, 110, 55, -48, -119, 74, -39, 58, 44, -63, -103, -73, -80, 57, 1, 64, -60, -33, -53, -21, 53, -45, -7, -42, 113, 60, 12, 38, 24, -66, 9, -111, 18, -108, -38, 30, 114, -77, -83, -9, 34, 88, -44, -114, -79, -54, -17, 44, 2, -36, -117, -74, 122, -62, -103, 14, 115, -39, 18, 73, -69, -77, -62, -111, -127, -102, -12, 90, 101, }),
}
Массив байтов для расшифровки:
[89, 250, 193, 103, 219, 4, 129, 208, 181, 30, 127, 250, 147, 113, 64, 25, 187, 96, 88, 15, 64, 93, 100, 141, 42, 89, 13, 157, 253, 187, 118, 154, 150, 132, 238, 224, 22, 98, 35, 252, 92, 253, 138, 6, 38, 142, 170, 247, 136, 19, 231, 48, 52, 228, 22, 222, 81, 242, 182, 109, 96, 209, 7, 187, 213, 237, 218, 147, 238, 28, 25, 217, 81, 200, 219, 76, 214, 232, 238, 193, 78, 252, 180, 45, 182, 150, 220, 157, 194, 11, 57, 195, 20, 174, 13, 123, 69, 72, 81, 112, 49, 143, 3, 67, 216, 86, 11, 234, 48, 210, 254, 136, 201, 238, 1, 222, 134, 178, 102, 230, 102, 137, 145, 236, 197, 2, 120, 106]
Однако когда я пытаюсь воспроизвести процесс расшифровки в Golang с помощью пакета crypto/rsa, я сталкиваюсь с проблемами. Реализация Go выглядит так:
func NewScrambledKeyPairTest(bits int) (ScrambledKeyPair, error) {
scrambledModulusJava := []byte{124, 168, 24, 242, 228, 213, 212, 54, 235, 100, 160, 114, 163, 61, 75, 218, 182, 245, 166, 34, 214, 132, 15, 71, 135, 194, 141, 227, 38, 1, 217, 145, 203, 135, 209, 137, 111, 33, 54, 34, 57, 0, 189, 243, 199, 219, 109, 56, 15, 225, 143, 59, 176, 108, 76, 204, 232, 133, 216, 126, 70, 30, 115, 74, 25, 0, 133, 38, 128, 16, 28, 183, 155, 24, 188, 86, 117, 191, 135, 36, 211, 165, 104, 217, 6, 182, 164, 136, 101, 215, 42, 113, 111, 55, 208, 207, 105, 35, 182, 47, 241, 107, 139, 215, 213, 249, 43, 125, 219, 34, 53, 103, 250, 92, 154, 128, 75, 189, 168, 128, 229, 6, 239, 177, 101, 126, 218, 75}
privateKey := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: big.NewInt(0).SetBytes([]byte{
0, 130, 204, 254, 101, 128, 16, 28, 185, 155, 24, 188, 86, 117, 15, 235, 104, 31, 165, 104, 217, 6, 182, 164, 136, 101, 215, 42, 113, 111, 55, 208, 207, 105, 35, 182, 47, 241, 107, 139, 215, 213, 249, 43, 125, 219, 34, 53, 103, 250, 92, 154, 128, 75, 189, 168, 128, 229, 6, 239, 177, 101, 126, 218, 75, 101, 168, 157, 212, 100, 197, 200, 129, 112, 124, 28, 36, 214, 25, 0, 133, 38, 80, 206, 251, 208, 50, 171, 207, 226, 21, 169, 146, 73, 54, 9, 94, 162, 164, 103, 166, 158, 74, 189, 245, 236, 249, 150, 142, 28, 249, 88, 95, 245, 189, 21, 187, 251, 209, 228, 76, 13, 131, 55, 207, 35, 96, 169, 1,
}),
E: 65537,
},
D: big.NewInt(0).SetBytes([]byte{
9, 61, 27, 118, 229, 221, 189, 121, 134, 125, 239, 199, 151, 139, 33, 80, 128, 115, 185, 125, 34, 201, 65, 195, 212, 149, 167, 12, 206, 19, 62, 47, 120, 56, 170, 132, 166, 99, 185, 67, 238, 124, 36, 3, 70, 184, 26, 215, 150, 74, 118, 43, 59, 174, 80, 185, 145, 243, 180, 120, 110, 55, 208, 137, 74, 217, 58, 44, 193, 153, 183, 176, 57, 1, 64, 196, 223, 203, 235, 53, 211, 249, 214, 113, 60, 12, 38, 24, 190, 9, 145, 18, 148, 218, 30, 114, 179, 173, 247, 34, 88, 212, 142, 177, 202, 239, 44, 2, 220, 139, 182, 122, 194, 153, 14, 115, 217, 18, 73, 187, 179, 194, 145, 129, 154, 244, 90, 101,
}),
}
return ScrambledKeyPair{
Pair: privateKey,
ScrambledModulus: scrambledModulusJava,
}, nil
}
func (p RequestLogin) Run(client *clients.Client, rand io.Reader) error {
privateKey := client.PrivateKey()
c := new(big.Int).SetBytes(p.raw)
m := new(big.Int)
m.Exp(c, privateKey.D, privateKey.N)
em := m.Bytes()
user := string(em[0x5E : 0x5E+14])
pwd := string(em[0x6C : 0x6C+16])
return nil
}
Но мне не удалось расшифровать эти байты:
[89, 250, 193, 103, 219, 4, 129, 208, 181, 30, 127, 250, 147, 113, 64, 25, 187, 96, 88, 15, 64, 93, 100, 141, 42, 89, 13, 157, 253, 187, 118, 154, 150, 132, 238, 224, 22, 98, 35, 252, 92, 253, 138, 6, 38, 142, 170, 247, 136, 19, 231, 48, 52, 228, 22, 222, 81, 242, 182, 109, 96, 209, 7, 187, 213, 237, 218, 147, 238, 28, 25, 217, 81, 200, 219, 76, 214, 232, 238, 193, 78, 252, 180, 45, 182, 150, 220, 157, 194, 11, 57, 195, 20, 174, 13, 123, 69, 72, 81, 112, 49, 143, 3, 67, 216, 86, 11, 234, 48, 210, 254, 136, 201, 238, 1, 222, 134, 178, 102, 230, 102, 137, 145, 236, 197, 2, 120, 106]
значение этих байтов после расшифровки в Java таково:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 97, 100, 109, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 100, 109, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Но в Golang я не могу, потому что в Java я использую: Cipher.getInstance("RSA/ECB/nopadding"); e В Golang я не нашел функции для расшифровки фрагмента байта без заполнения.
Что значит...Но у меня не получается расшифровать...? Неправильный результат (опубликовать результат), исключение (опубликовать трассировку исключения/стека)...? В чем разница между зашифрованным ключом ([124, 168,...
) и массивом байтов для расшифровки ([89, 250,...
)?
Ваш код не является исполняемым напрямую, и вы не описываете точно, в чем проблема (неправильный результат, исключение...). Когда я запускаю расшифровку (модульное возведение в степень) ваших данных:
ciphertextBytes := ([]byte{89, 250, 193, 103, 219, 4, 129, 208, 181, 30, 127, 250, 147, 113, 64, 25, 187, 96, 88, 15, 64, 93, 100, 141, 42, 89, 13, 157, 253, 187, 118, 154, 150, 132, 238, 224, 22, 98, 35, 252, 92, 253, 138, 6, 38, 142, 170, 247, 136, 19, 231, 48, 52, 228, 22, 222, 81, 242, 182, 109, 96, 209, 7, 187, 213, 237, 218, 147, 238, 28, 25, 217, 81, 200, 219, 76, 214, 232, 238, 193, 78, 252, 180, 45, 182, 150, 220, 157, 194, 11, 57, 195, 20, 174, 13, 123, 69, 72, 81, 112, 49, 143, 3, 67, 216, 86, 11, 234, 48, 210, 254, 136, 201, 238, 1, 222, 134, 178, 102, 230, 102, 137, 145, 236, 197, 2, 120, 106})[0:128]
modulusInt := "91851415039980683673835443907833548355613725060429787547716446884026400945844827342368025805543719063805785824109075005634172820422680533076648130137521254244221874431195148950936257983839718841574094615493929797376689026996944801887459231860502077721291214210394902757594184173778070286729141127782416296193"
privateExpInt := "6487635995240407475566233880851450254636860602479965310563184653343274943593934811905055029279061836006484620592961353145255138101173202734513392349460393317252650745961877082056763589015732603463063131507792018004450541681668317154023863374611531824451608552071840032997073721859882730955156029598795586149"
c := new(big.Int)
c.SetBytes(ciphertextBytes)
n := new(big.Int)
n.SetString(modulusInt, 10)
d := new(big.Int)
d.SetString(privateExpInt, 10)
decrypted := new(big.Int).Exp(c, d, n).Bytes()
fmt.Println(hex.EncodeToString(decrypted)) // 24000061646d696e00000000000000000061646d696e000000000000000000000000000000
Я получаю правильный результат (в шестнадцатеричном кодировании):
24000061646d696e00000000000000000061646d696e000000000000000000000000000000
Единственное отличие от результата кода Java состоит в том, что код Java автоматически дополняет результат спереди значениями 0x00 до размера/модуля ключа, тогда как при прямом модульном возведении в степень этого, конечно, не происходит.
Чтобы это исправить, вы можете просто дополнить себя, чтобы индексы были правильными, например:
decryptedPadded := append(make([]byte, 128-len(decrypted)), decrypted...)
fmt.Println(hex.EncodeToString(decryptedPadded[0x5E : 0x5E+14])) // 61646d696e000000000000000000
fmt.Println(string(decryptedPadded[0x5E : 0x5E+14])) // admin
Безопасность. Как уже упоминалось в комментарии, шифрование RSA без заполнения небезопасно. Кроме того, в настоящее время следует использовать ключ размером не менее 2048 бит (256 байт).
Обновлено: код, указанный в вашем комментарии, использует неправильные массивы байтов для модуля и частного показателя. Правильные значения можно вывести следующим образом, например: для модуля:
modulusInt := "91851415039980683673835443907833548355613725060429787547716446884026400945844827342368025805543719063805785824109075005634172820422680533076648130137521254244221874431195148950936257983839718841574094615493929797376689026996944801887459231860502077721291214210394902757594184173778070286729141127782416296193"
n := new(big.Int)
n.SetString(modulusInt, 10)
fmt.Println(n.Bytes()) // [130 204 254 101 128 16 28 183 155 24 188 86 117 15 235 104 31 165 104 217 6 182 164 136 101 215 42 113 111 55 208 207 105 35 182 47 241 107 139 215 213 249 43 125 219 34 53 103 250 92 154 128 75 189 168 128 229 6 239 177 101 126 218 75 101 168 157 212 100 197 200 129 112 124 28 36 214 25 0 133 38 80 206 251 208 50 171 207 226 21 167 146 73 54 9 94 162 164 103 166 158 74 189 245 236 249 150 142 28 249 88 95 245 189 21 187 251 209 228 76 13 131 55 207 35 96 169 1]
То же самое и с частным экспонентом. При сравнении со своими значениями вы обнаружите отклонения в несколько байт.
Это приводит к следующему для закрытого ключа:
privateKey := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: big.NewInt(0).SetBytes([]byte{130, 204, 254, 101, 128, 16, 28, 183, 155, 24, 188, 86, 117, 15, 235, 104, 31, 165, 104, 217, 6, 182, 164, 136, 101, 215, 42, 113, 111, 55, 208, 207, 105, 35, 182, 47, 241, 107, 139, 215, 213, 249, 43, 125, 219, 34, 53, 103, 250, 92, 154, 128, 75, 189, 168, 128, 229, 6, 239, 177, 101, 126, 218, 75, 101, 168, 157, 212, 100, 197, 200, 129, 112, 124, 28, 36, 214, 25, 0, 133, 38, 80, 206, 251, 208, 50, 171, 207, 226, 21, 167, 146, 73, 54, 9, 94, 162, 164, 103, 166, 158, 74, 189, 245, 236, 249, 150, 142, 28, 249, 88, 95, 245, 189, 21, 187, 251, 209, 228, 76, 13, 131, 55, 207, 35, 96, 169, 1}),
E: 65537,
},
D: big.NewInt(0).SetBytes([]byte{9, 61, 27, 118, 229, 221, 189, 121, 134, 125, 239, 199, 151, 139, 33, 80, 128, 115, 185, 125, 34, 201, 65, 195, 212, 149, 167, 12, 206, 19, 62, 47, 120, 56, 170, 132, 166, 99, 183, 67, 238, 124, 36, 3, 70, 184, 26, 215, 150, 74, 118, 43, 59, 174, 80, 185, 145, 243, 180, 120, 110, 55, 208, 137, 74, 217, 58, 44, 193, 153, 183, 176, 57, 1, 64, 196, 223, 203, 235, 53, 211, 249, 214, 113, 60, 12, 38, 24, 190, 9, 145, 18, 148, 218, 30, 114, 179, 173, 247, 34, 88, 212, 142, 177, 202, 239, 44, 2, 220, 139, 182, 122, 194, 153, 14, 115, 217, 18, 73, 187, 179, 194, 145, 129, 154, 244, 90, 101}),
}
При этом расшифровка работает.
Простите меня за отрицательный голос, это был промах, я жду момента, чтобы проголосовать за, извините !!
может мне помочь здесь: go.dev/play/p/b7DyQpweidd? я использую закрытый ключ и безуспешно:/
если я использую rsa.PrivateKey, не работает:/
@Ming - Ваши массивы байтов для модуля и частной экспоненты неверны, см. раздел редактирования в моем ответе и для иллюстрации go.dev/play/p/oZC0pdJ8tt_u и go.dev/play/p/9fZ8te4JX9g
Не опасно ли использовать RSA без заполнения gg? Конечно, вы это знаете :) crypto.stackexchange.com/questions/1448/… вы пробовали использовать rsa.DecryptPKCS1v15, но он с заполнением, поэтому вам нужно вручную удалить заполнение после расшифровки. По возможности используйте прокладку, более безопасную и лучшую совместимость.