Я хотел бы добиться чего-то, что я считал довольно простым:
A) Мой клиент VB.NET (в идеале ориентированный на Framework 4.0) отправляет текстовую строку на мой сервер Apache/PHP через HTTPS-запрос POST.
Б) Мой сервер отвечает подписью этой текстовой строки. Закрытый ключ, используемый Сервером, всегда один и тот же, а открытый ключ, используемый Клиентом, уже встроен в исходный код.
После изучения и прочтения большого количества документации я пришел к следующей стратегии и задал два вопроса:
<?
// Create new Keys Pair
$new_key_pair = openssl_pkey_new(array(
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
));
//Save Private Key
openssl_pkey_export($new_key_pair, $private_key_pem, "my passphrase to protect my private key; add random characters like $, ?, #, & or ! for improved security");
file_put_contents('private_key.pem', $private_key_pem);
//Save Public Key
$details = openssl_pkey_get_details($new_key_pair);
$public_key_pem = $details['key'];
file_put_contents('public_key.pem', $public_key_pem);
?>
<?
header('Content-Type: text/plain; charset=utf-8');
// Verify connection is secure
if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS']= = "off")
{
echo "Unauthorized Access";
exit;
}
// Data to Sign
$data = base64_decode(file_get_contents('php://input'));
//Load Private Key
$private_key_pem = openssl_pkey_get_private('file:///path/protected/by/dotHtaccess/private_key.pem', "my passphrase to protect my private key; add random characters like $, ?, #, & or ! for improved security");
//Create Signature
openssl_sign($data, $signature, $private_key_pem, OPENSSL_ALGO_SHA256);
echo base64_encode($signature);
?>
imports System.Diagnostics
Sub mySignatureTest()
Dim oURI As Uri = New Uri("https://www.example.com/targetpage.php")
Dim sData As String = "myStringToSign"
Dim sResponse As String
'# Get POST request Response
Using oWeb As New System.Net.WebClient()
Try
System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol And Not System.Net.ServicePointManager.SecurityProtocol.Ssl3 'Override defautl Security Protocols: Prohibit SSL3
oWeb.Encoding = Encoding.UTF8
Debug.Print("SSL version is " & System.Net.ServicePointManager.SecurityProtocol.ToString)
Debug.Print("Sending " & sData)
Debug.Print("To " & oURI.ToString)
Debug.Print("Encoding is " & oWeb.Encoding.ToString)
sResponse = oWeb.UploadString(oURI, "POST", Convert.ToBase64String(Encoding.UTF8.GetBytes(sData)))
Debug.Print("Server reponse = " & sResponse)
Catch ex As Exception
MsgBox("Connection with server failed: " & ex.ToString, vbCritical + vbOKOnly, "Add-In")
End Try
End Using
'#Verify RSA SHA256 Signature
Dim sDataToSign As String = sData
Dim sSignatureToVerify As String = sResponse
Using myRSA As New System.Security.Cryptography.RSACryptoServiceProvider
'XML format obtain from PEM file by hand copy/paste here: https://superdry.apphb.com/tools/online-rsa-key-converter
myRSA.FromXmlString("<RSAKeyValue><Modulus>SomeLongBase64StringHere</Modulus><Exponent>SomeShortBase64StringHere</Exponent></RSAKeyValue>")
Debug.Print("Signature verification = " & myRSA.VerifyData(Encoding.UTF8.GetBytes(sDataToSign), _
System.Security.Cryptography.CryptoConfig.MapNameToOID("SHA256"), _
Convert.FromBase64String(sSignatureToVerify)).ToString)
End Using
End Sub
После того, как вопрос 2) будет решен, я надеюсь, что мы сможем доработать этот код, чтобы он стал хорошим, но все же простым примером того, как реализовать .NET Client проверку подписи OpenSSL Server. Я не смог найти простой и понятный пример в Интернете.
Обычно это можно использовать для целей лицензирования, когда сервер предоставляет файл, содержащий дату истечения срока действия, а также подпись этой даты, чтобы клиентское приложение могло подтвердить, что эта дата истечения срока действия не была изменена, например, владельцем клиента. компьютер.
Вопрос 2) не относится к теме переполнения стека, поэтому перемещен в обзор кода здесь: codereview.stackexchange.com/questions/212989/…






Вопрос 2) решен: по какой-либо причине передача ответа POST через строку в кодировке base64 решает проблему. Я не уверен, почему, поскольку я проводил аналогичные тесты с хеш-значениями без необходимости кодирования base64. Вопрос был отредактирован, чтобы включить это исправление.