我需要通过TCP连接将机密数据发送到服务器.我做了很多研究,理解了理论部分.根据我研究的内容,我想做以下事情:
注意有一个服务器和一个客户端:(我们假设任何人都可以获得客户端或服务器的公钥)
客户端创建他的公钥和私钥.他能够用他的私钥加密并用他的公钥解密.
服务器创建他的公钥和私钥.私钥用于解密消息,公钥用于加密消息.(注意与客户端相反)
客户端获取服务器的公钥.然后,客户端将能够使用该密钥加密消息,并且唯一能够解密该消息的消息将是服务器的私钥.
由于服务器需要确定消息来自该特定客户端,因此客户端将使用其私钥加密其名称(签名).
因此客户端消息将包含:要发送的数据,客户端的公钥,使用客户端私钥加密的客户端名称.
客户端将使用服务器中的公钥加密消息.然后,客户端将该消息发送到服务器.
服务器将使用他的私钥解密刚刚收到的消息.
一旦消息被解密,它将包含来自客户端的数据(信息),加密签名,公钥.
最后,服务器将使用消息中包含的公钥解密客户端签名,以验证消息是否来自该客户端.
好的,这就是非对称加密的工作原理.我还研究过使用.NET框架创建这些密钥对的类.我研究过的可以创建此公钥和私钥对的类是:
System.Security.Cryptography.DES
System.Security.Cryptography.DSACryptoServiceProvider
System.Security.Cryptography.ECDsa
System.Security.Cryptography.ECDsaCng
System.Security.Cryptography.ECDiffieHellman
System.Security.Cryptography.ECDiffieHellmanCng
System.Security.Cryptography.RSA
System.Security.Cryptography.RSACryptoServiceProvider
Run Code Online (Sandbox Code Playgroud)
所以现在我的问题出现在如何使用这个类中的一个用C#来完成它?我理解理论部分是如何工作的,但我怎么做我刚才用代码描述的东西.我研究了一些例子,但我很难理解它们.
这是我发现我相信我所描述的一个例子:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Example
{
class Program
{
static CngKey aliceKey;
static CngKey bobKey;
static byte[] alicePubKeyBlob;
static byte[] bobPubKeyBlob;
static void Main()
{
CreateKeys();
byte[] encrytpedData = AliceSendsData("secret message");
BobReceivesData(encrytpedData);
Console.Read();
}
private static void CreateKeys()
{
aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
}
private …Run Code Online (Sandbox Code Playgroud) 我已经设法使用MSDN上的示例加密和解密xml文档. http://msdn.microsoft.com/en-us/library/ms229744.aspx和 http://msdn.microsoft.com/en-us/library/ms229943.aspx
这都是根据W3C XML加密标准(XML Enc)完成的.
这一切都很好.我的问题是一个xml文档适用于2或3个收件人.我想用多个密钥(X509证书公钥)加密相同的xml,以便多个收件人可以解密文档.
根据W3C XML加密标准,通过使用包含加密对称会话密钥的多个EncryptionKey元素,这一切都是可能的.
我找不到任何关于如何使用标准加密类在.Net中实现此目的的示例.
这必须在.NET C#中实现.
有没有办法在某处做这个或代码示例?
我需要调用 Web 服务,我必须使用 C# 在下面发送这样的肥皂请求。SoapBody 和 TimeStamp 必须签名。
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://xyzt.com/">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="X509-F4AF9673207AC5E0B614180667985061">MIIFsDCCBawwggSUoAMCAQICBgCaWhnEajANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJUUjFNMEsGA1UEAwxETWFsaSBNw7xow7xyIEVsZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgLSBTw7xyw7xtIDEwHhcNMT</wsse:BinarySecurityToken>
<ds:Signature Id="SIG-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="soap web" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#id-2">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="web" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>IZVrIpPCxiPcvyVOVv/d4nRPZWM=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#TS-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="wsse soap web" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>fltghgDztDtuVQX7y4t0ZJxAnxE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>IOVXxBTp053aNJMbQj+VTiBblZ63peyJ1vWazKmEWNxN7RaeFfKELoxede8xQEqzSaB/u8exC7LLGYiEdChboVCf9liLMN4MmNj5JR6gfDrsL3azThf5hxLQ+WIE20PRoU6ozpp20zC1IaO3IU4ZaRLw</ds:SignatureValue>
<ds:KeyInfo Id="KI-F4AF9673207AC5E0B614180667986422">
<wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="STR-F4AF9673207AC5E0B614180667986643" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
<wsse:Reference URI="#X509-F4AF9673207AC5E0B614180667985061" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-1">
<wsu:Created>2014-12-08T21:26:36.191Z</wsu:Created>
<wsu:Expires>2014-12-08T21:36:36.191Z</wsu:Expires> …Run Code Online (Sandbox Code Playgroud) Microsoft页面提供有关CngKey.Import可以使用的格式的"最小"信息.以下属性实际表示哪些实际格式CngKeyBlobFormat?
EccPrivateBlob EccPublicBlob GenericPrivateBlob GenericPublicBlobOpaqueTransportBlobPkcs8PrivateBlob只有PKCS#8私钥格式略微提示密钥的格式,但它没有指定是否需要包装私钥或者是否接受内部PKCS#8结构.
当然,关于这些格式的信息越多越好.
假设我有一个像
gen = (i*2 for i in range(100))
Run Code Online (Sandbox Code Playgroud)
我现在想创建一个包含生成器产生的所有值的字节对象。我可以执行以下操作:
b = bytes(gen)
Run Code Online (Sandbox Code Playgroud)
我现在的问题是:由于bytes对象是不可变的,在这种情况下内存分配如何工作?我是否必须假设对于生成器产生的每个元素,都会bytes创建一个新对象,并将先前的内容加上另一个元素复制到其中?这将是非常低效的,尤其是对于更大长度的生成器。而且由于生成器不提供任何长度信息,似乎没有任何其他方式可以在内部预先分配所需的内存。
再说一次,在尽可能少的内存使用情况下,实现这一目标的更好方法是什么?如果我先使用(可变的)bytearray并将其转换为bytes对象?
b = bytes(bytearray(gen))
Run Code Online (Sandbox Code Playgroud)
甚至是一个清单?
b = bytes(list(gen))
Run Code Online (Sandbox Code Playgroud)
但这看起来有点奇怪和违反直觉......
背景:我使用的特定生成器通过来自另一个模块 (.pyd) 的 C-API 一次读取一个字节(作为 0..255 中的 Python 整数),并且序列的总长度事先已知,向上到那里的 2**25 个字节。我的读出函数应该收集这些并返回一个bytes我认为合适的对象,因为数据是只读的。
Java 9引入了一个新的名为DRBG的SecureRandom。我想用它来确定性地生成随机数。问题在于它在内部使用一个随时更改的随机数,因此对于相同的种子,我不会得到相同的数字。它的内部确实有一个选项可以设置该随机数,但是我找不到任何可以完成该操作的公共方法。如何更改该随机数?
出于某些原因,我需要使用256位的块大小来实现Rijndael de/compression,而不是使用128位块大小的AES(原因:数据使用Rijndael在PHP中加密......).
如何更改密码的块大小?
如果我只是得到一个密码,"RIJNDAEL/CFB/PKCS5Padding"并尝试初始化一个256位的IV,我得到一个例外,因为块大小只有128位.
我有以下使用Bouncy Castle for C#创建加密私钥的方法:
public string GetPrivateKey(AsymmetricCipherKeyPair keyPair, string password)
{
var generator = new Pkcs8Generator(keyPair.Private, Pkcs8Generator.PbeSha1_3DES);
generator.IterationCount = 4;
generator.Password = password.ToCharArray();
var pem = generator.Generate();
TextWriter textWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(pem);
pemWriter.Writer.Flush();
string privateKey = textWriter.ToString();
return privateKey;
}
Run Code Online (Sandbox Code Playgroud)
看起来像这样:
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
我不知道如何在Decrypt方法中使用用于加密私钥的密码。现在,在不知道如何使用he来“解密”我的私钥password的情况下,我得到了以下异常:
Org.BouncyCastle.OpenSsl.PemException:创建ENCRYPTED私钥时出现问题:System.NullReferenceException:对象引用未设置为对象的实例。在Org.BouncyCastle.OpenSsl.PemReader.ReadPrivateKey(PemObject pemObject)
这是Decrypt方法的代码:
public string Decrypt(string base64Input, string privateKey, string password)
{
var bytesToDecrypt = Convert.FromBase64String(base64Input);
//get a stream from the …Run Code Online (Sandbox Code Playgroud) 我目前正在开发一个限制性环境,其中允许的唯一类型是:
byte, byte[], short, short[].
Run Code Online (Sandbox Code Playgroud)
我几乎可以肯定我无法导入外部库,因为我正在研究JavaCard,并且已经尝试过这样的事情,但结果并不好.
所以,在这里我必须管理一个大小为6字节的字节数组,它代表卡的余额(欧元),最后一个字节是美分,但现在这并不重要.
鉴于我无法访问整数,我不知道如何以我想要的方式添加两个字节.
我们举个例子:
用户输入(添加)0x00 0x00 0x00 0x00 0x00 0x57,这对用户来说意味着增加57美分.我们现在说平衡是0x00 ... 0x26.
我希望能够创建一种方法,可以修改平衡数组(带有进位),添加后,分数为83,并表示0x83.我也必须处理减法,但我想我之后可以自己解决这个问题.
我的第一个猜测是掩盖每个字节的每个数字,并且首先单独工作,但这让我无处可去.
我显然不是要求一个完整的解决方案,因为我相信我的问题几乎是不可能的,但如果你对如何处理这个问题有任何想法,我将非常感激.
那么如何在Java Card上相互添加两个包含二进制编码小数的数组呢?
编辑1:常见的数组如下所示:
{ 0x00 , 0x00 , 0x01, 0x52, 0x45, 0x52}
Run Code Online (Sandbox Code Playgroud)
并且代表15 254€和52美分的大端BCD编码整数.
编辑2:嗯,我怀疑,我的卡不支持包framework.math,所以我不能使用BCDUtil或BigNumbers,这将是有用的.
我对 ECC 不熟悉,如果这个问题有点奇怪/愚蠢,我很抱歉。
我正在使用一些第三方存储库(Private Join and Compute)实现一些协议,并且在创建 EC 组时,该存储库仅支持 openssl 中 FIPS 模块(P-224、256、348 和 512)中的内置曲线:
StatusOr<ECGroup::ECGroupPtr> CreateGroup(int curve_id) {
auto ec_group_ptr = EC_GROUP_new_by_curve_name(curve_id);
// If this fails, this is usually due to an invalid curve id.
if (ec_group_ptr == nullptr) {
return InvalidArgumentError(
absl::StrCat("ECGroup::CreateGroup() - Could not create group. ",
OpenSSLErrorString()));
}
return ECGroup::ECGroupPtr(ec_group_ptr);
}
Run Code Online (Sandbox Code Playgroud)
(EC_GROUP_new_by_curve_name位于 openssl/crypto/fipsmodule 中)
我的问题:
我可以修改代码以将我的协议的内置曲线替换为 X25519 吗?我的协议将其用于 ECDH。
如果不是,除了 X25519 未经 FIPS 验证之外还有什么问题?
或者,简单地说,在什么用例中我应该使用 secp256r1/k1,而对于 X25519 又应该使用什么?
谢谢!
cryptography ×6
c# ×5
encryption ×4
java ×3
standards ×2
.net ×1
aes ×1
arrays ×1
bcd ×1
bouncycastle ×1
c++ ×1
certificate ×1
cng ×1
generator ×1
javacard ×1
pem ×1
private-key ×1
python ×1
python-3.x ×1
random ×1
rijndael ×1
soap ×1
web-services ×1
ws-security ×1
xml ×1