Шифрование с использованием .NET Framework и JavaScript с самого сгенерированным сертификатомC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Шифрование с использованием .NET Framework и JavaScript с самого сгенерированным сертификатом

Сообщение Anonymous »

Я пытаюсь разработать какую -то шифрование конечного в конце, используя 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»