2012-06-14 3 views
6

Я пытаюсь порт следующий Java-код к C# эквивалент:Порт RSA шифрование кода Java в C#

public static String encrypt(String value, String key) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 
    byte[] bytes = value.getBytes(Charset.forName("UTF-8")); 
    X509EncodedKeySpec x509 = new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(key)); 
    KeyFactory factory = KeyFactory.getInstance("RSA"); 
    PublicKey publicKey = factory.generatePublic(x509); 
    Cipher cipher = Cipher.getInstance("RSA"); 
    cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
    bytes = cipher.doFinal(bytes); 
    return DatatypeConverter.printBase64Binary(bytes); 
} 

До сих пор мне удалось написать в C#, используя библиотеку BouncyCastle для .NET :

public static string Encrypt(string value, string key) 
    { 
     var bytes = Encoding.UTF8.GetBytes(value); 
     var publicKeyBytes = Convert.FromBase64String(key); 
     var asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKeyBytes); 
     var rsaKeyParameters = (RsaKeyParameters) asymmetricKeyParameter; 
     var cipher = CipherUtilities.GetCipher("RSA"); 
     cipher.Init(true, rsaKeyParameters); 
     var processBlock = cipher.DoFinal(bytes); 
     return Convert.ToBase64String(processBlock); 
    } 

Эти два метода, однако, дают разные результаты, даже если вызываются с теми же параметрами. Для целей тестирования, я использую следующий открытый ключ RSA:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLCZahTj/oz8mL6xsIfnX399Gt6bh8rDHx2ItTMjUhQrE/9kGznP5PVP19vFkQjHhcBBJ0Xi1C1wPWMKMfBsnCPwKTF/g4yga6yw26awEy4rvfjTCuFUsrShSPOz9OxwJ4t0ZIjuKxTRCDVUO7d/GZh2r7lx4zJCxACuHci0DvTQIDAQAB 

Не могли бы вы мне помочь в порт код Java успешно или предложить альтернативу, чтобы получить тот же результат в C#?

EDIT1: вывод в Java различен при каждом запуске программы. Я не думаю, что какое-либо дополнение было указано, поэтому я не понимаю, что делает вывод случайным.

EDIT2: Java использует PKCS1 по умолчанию, так что было достаточно, чтобы указать его в инициализации # шифра C, чтобы получить тот же тип шифрования (хотя и не тот же самый результат, который не имеет никакого значения в этой точке).

+0

Больше просто интересно, но, несмотря на то, что они выплюнули разные ответы, дают ли они те же самые входы, когда вы их расшифровываете? –

+0

Да, строки с расширением UTF8 являются одинаковыми и, по-видимому, являются модулем и показателем двух ключевых структур (PublicKey в Java, RsaKeyParameters в C#) идентичны. Я не пытаюсь расшифровать результаты, поскольку мне это не нужно, и программа не требует закрытого ключа. – user1098567

+2

Duplicate? http://stackoverflow.com/questions/4758321/java-rsa-encryption-non-repeatable –

ответ

1

Как явное обоснование, я бы сказал, что Java добавляет случайное дополнение для создания более сильного шифрования.

Большинство практических реализаций RSA сделать это, и как wiki выразился ...

Поскольку шифрование RSA является детерминированный алгоритм шифрования - т.е. не имеет случайную составляющую - злоумышленник может успешно запустить выбранный атаку открытого текста против криптосистемы, путем шифрования вероятных открытых текстов под открытым ключом и проверки, если они равны зашифрованному тексту. Криптосистема называется семантически безопасной, если злоумышленник не может отличить две шифровки друг от друга, даже если злоумышленник знает (или выбрал) соответствующие открытые тексты. Как описано выше, RSA без заполнения не является семантически безопасным.

Это, скорее всего, почему ваши два метода не выдают то же самое.

Смежные вопросы