Я пытаюсь разработать какую -то шифрование конечного в конце, используя C# .NET Framework на стороне сервера и JavaScript на стороне клиента, это то, что мне нужно: < /p>
[*] генерирование соли на стороне клиента и отправка соли + уникальный номер устройства (у меня есть) на сервер. < /p>
< /li>
На сервере, используя номер устройства, который мне нужен для создания самого сгенерированного сертификата с частным и открытым ключом, затем зашифруйте закрытый ключ, используя прислатную соль, и отправьте зашифрованный закрытый ключ обратно в клиент.
В клиенте мне нужно расшифровать ключ, используя ту же соль и использовать ее для шифрования определенной полезной нагрузки перед отправкой на сервер.
< /li>
расшифровывать полезную нагрузку, используя открытый ключ (я хранил его в DB для этого) и продолжайте регулярно. < /p>
< /li>
< /ol>
Независимо от того, что я попробовал, я не могу преодолеть 3, так как я терплю неудачу на дешифровании на стороне клиента (возможно, проблема с Шифрование на стороне сервера, я не уверен). < /p>
Любая помощь будет оценена. Пробовал еще много):
Сторона сервера:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web.Http;
[HttpPost]
[Route("api/device/certificate")]
public IHttpActionResult GenerateDeviceCertificate([FromBody] CertificateRequestModel request)
{
try
{
// Create certificate with private key
var subjectName = $"CN={request.DeviceNumber}";
var rsa = new RSACryptoServiceProvider(2048);
var req = new CertificateRequest(subjectName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var cert = new X509Certificate2(req.CreateSelfSigned(
DateTimeOffset.Now,
DateTimeOffset.Now.AddYears(1)).Export(X509ContentType.Pfx),
(string)null,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
// Get private key
var privateKey = cert.PrivateKey as RSACryptoServiceProvider;
if (privateKey == null)
throw new Exception("Failed to get private key from certificate");
var privateKeyBytes = privateKey.ExportCspBlob(true);
// Encrypt the private key using AES with the provided salt
byte[] saltBytes = Encoding.UTF8.GetBytes(request.Salt);
using (Aes aes = Aes.Create())
{
using (var keyDerivation = new Rfc2898DeriveBytes(request.Salt, saltBytes, 10000))
{
aes.Key = keyDerivation.GetBytes(32);
aes.GenerateIV();
byte[] encryptedPrivateKey = EncryptAES(privateKeyBytes, aes.Key, aes.IV);
return Ok(new
{
success = true,
encryptedPrivateKey = Convert.ToBase64String(encryptedPrivateKey),
iv = Convert.ToBase64String(aes.IV)
});
}
}
}
catch (Exception ex)
{
return Ok(new
{
success = false,
error = ex.Message
});
}
}
// AES Encryption Helper
private byte[] EncryptAES(byte[] data, byte[] key, byte[] iv)
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
using (var encryptor = aes.CreateEncryptor())
{
return encryptor.TransformFinalBlock(data, 0, data.Length);
}
}
}
сторона клиента:
async function requestKeyFromServer() {
// Generate a random salt for key encryption
const salt = crypto.getRandomValues(new Uint8Array(16))
.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
// Prepare request data
const certificateRequest = {
deviceNumber: _userDevice,
salt: salt
};
// Send to server to generate certificate
try {
const response = await fetch(_urlBase + 'api/device/certificate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(certificateRequest)
});
const result = await response.json();
if (result.success) {
// Decrypt the private key using the same salt
_privateKey = await decryptPrivateKey(result.encryptedPrivateKey, salt, result.iv);
// Store the decrypted private key securely
//storeKey(response.encryptedPrivateKey, salt, response.Expiry);
} else {
throw new Error(result.error || 'Failed to generate certificate');
}
} catch (error) {
console.error('Certificate generation failed:', error);
throw error;
}
}
async function decryptPrivateKey(encryptedPrivateKey, salt, iv) {
const aesKey = await deriveKey(salt);
const encryptedData = Uint8Array.from(atob(encryptedPrivateKey), c => c.charCodeAt(0));
const ivBytes = Uint8Array.from(atob(iv), c => c.charCodeAt(0));
const decrypted = await crypto.subtle.decrypt(
{ name: "AES-CBC", iv: ivBytes },
aesKey,
encryptedData
);
return new TextDecoder().decode(decrypted);
}
async function deriveKey(salt) {
const saltBytes = new TextEncoder().encode(salt); // Convert salt string to Uint8Array
// Import key material (PBKDF2 requires a key material, which is a raw buffer from the salt)
const keyMaterial = await crypto.subtle.importKey(
"raw",
saltBytes, // Corrected: Import the salt as raw key material
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"]
);
// Derive AES key from PBKDF2
return await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: saltBytes,
iterations: 100000, // Higher is more secure
hash: "SHA-256"
},
keyMaterial,
{ name: "AES-CBC", length: 256 }, // Derive a 256-bit AES key
true,
["encrypt", "decrypt"]
);
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... ertificate
Шифрование с использованием .NET Framework и JavaScript с самого сгенерированным сертификатом ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Шифрование RSA в .Net Framework 4.8 с использованием RSAEncryptionPadding.OaepSHA256
Anonymous » » в форуме C# - 0 Ответы
- 15 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Использование обнаружения службы .Net Aspire с сгенерированным клиентом (генератор openapi)
Anonymous » » в форуме C# - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-