Я работаю над функцией, которая требует от меня цифровой подписи короткой строки в PHP и проверки подписи строки на C #.
Я бы очень хотел использовать openssl_sign в PHP из-за его простоты, но вся информация, которую я могу найти в Google, показывает, что это не сработает.
Есть некоторые внешние библиотеки, которые утверждают, что делают это хорошо, однако, поскольку это хобби-проект, я бы предпочел не покупать такую библиотеку.
Итак, каковы альтернативы здесь? Требуется полная совместимость между C # и PHP. Можно использовать библиотеки, кроме OpenSSL.
Я сделал что-то очень похожее, используя Bouncy Castle Crypto API . Похоже, что PHP openssl_sign по умолчанию использует SHA1. Если вы используете что-либо другое, кроме значения по умолчанию, вам нужно будет изменить параметр алгоритма для GetSigner.
string base64pubkey = "<!-- BASE64 representation of your pubkey from open ssl -->"; RsaKeyParameters pubKey = PublicKeyFactory.CreateKey(Convert.FromBase64String(base64pubkey)) as RsaKeyParameters; byte[] signature = Convert.FromBase64String("<!-- BASE64 representation of your sig -->"); byte[] message = Encoding.ASCII.GetBytes("Something that has been signed"); ISigner sig = SignerUtilities.GetSigner("SHA1WithRSAEncryption"); sig.Init(false, pubKey); sig.BlockUpdate(message, 0, message.Length); if (sig.VerifySignature(signature)) { Console.WriteLine("all good!"); }
Вы можете использовать для проверки цифровой подписи smth следующим образом:
string publicKey = "some key"; // Verifying Step 1: Create the digital signature algorithm object DSACryptoServiceProvider verifier = new DSACryptoServiceProvider(); // Verifying Step 2: Import the signature and public key. verifier.FromXmlString(publicKey); // Verifying Step 3: Store the data to be verified in a byte array FileStream file = new FileStream(args[0], FileMode.Open, FileAccess.Read); BinaryReader reader = new BinaryReader(file2); byte[] data = reader.ReadBytes((int)file2.Length); // Verifying Step 4: Call the VerifyData method if (verifier.VerifyData(data, signature)) Console.WriteLine("Signature verified"); else Console.WriteLine("Signature NOT verified"); reader.Close(); file.Close();
Есть ли причина, по которой вам нужно что-то сложное, как подписывание SSL? Не можете ли вы просто использовать простой односторонний хэш, например MD5 / SHA-1 на строке? Если все, что вам нужно, это проверка того, что строка не была изменена, этого должно быть достаточно.
Поэтому, глядя на это, у этого парня есть асимметричное подписание и шифрование, работающее между PHP и C #. Подписание не должно быть проблемой, SHA * и MD * являются стандартными, и поэтому очень маловероятно, что это будет несовместимо (хотя вы должны смотреть на SHA256, поскольку MD * и SHA1 устарели из-за уязвимостей)
Нам не хватает какого-либо контекста относительно того, почему вам нужно его подписать. Вам может и не понадобиться.
Важный вопрос: какие гарантии вам нужны из ваших данных?
Если все, что вам нужно сделать, это проверить целостность данных, хеш выполнит задание. Если вам нужно проверить, откуда он, вам нужно подписать его. Если вам нужны оба, хеш, объедините полезную нагрузку с хешем и подпишите все это.
Что касается кросс-платформенных библиотек … вам действительно нужно беспокоиться об этом. SHA1 является SHA1, является SHA1, независимо от того, какая библиотека сгенерировала его. То же самое происходит с генерацией и проверкой цифровых подписей. Используйте то, что проще всего в PHP, и используйте то, что проще всего на C #. Если они оба настроены правильно, вам не стоит беспокоиться об этом.