I am pretty much new to cryptographic. So far I am successful to generate an enveloped CMS file. But after it, I need to encode a CMS Signed and encrypted data file using ASN.1 DER format but don't know how to? please provide me some suggestion.
below I paste my code for more light;
var content = File.ReadAllBytes(#"E:\Miscellaneous\Pacs.zip");
var contentInfo1 = new ContentInfo(content);
var signedCms = new SignedCms(contentInfo1);
var cmsSigner = new CmsSigner(GetSignerCert()) { IncludeOption = X509IncludeOption.None };
signedCms.ComputeSignature(cmsSigner);
var contentInfo = new ContentInfo(signedCms.Encode());
// RSA_DES_EDE3_CBC.
var envelopedCms = new EnvelopedCms(contentInfo);
var recip1 = new CmsRecipient(
SubjectIdentifierType.IssuerAndSerialNumber,
GetRecipientCert());
envelopedCms.Encrypt(recip1);
File.WriteAllBytes(#"E:\signedfile", envelopedCms.Encode());
// need code to encode signedfile using ASN.1 DER
EnvelopedCms.Encode() is specified to create bytes, but the only way to do that is to use an encoding method. It is about 99% certain that that encoding is ASN.1 BER or DER. So it is extremely likely that you've already accomplished your goal.
Related
I'm using BouncyCastle to sign transactions for the EOS blockchain. Similar to Bitcoin signatures, the signature needs to have a "recovery ID" as the 1st bytes. My code looks as follows:
var curve = SecNamedCurves.GetByName("secp256r1");
var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
var p = new Org.BouncyCastle.Math.BigInteger(privateKey);
var keyParameters = new ECPrivateKeyParameters(
new Org.BouncyCastle.Math.BigInteger(1,privateKey),
domain);
ISigner signer = SignerUtilities.GetSigner("SHA-256withPLAIN-ECDSA");
signer.Init(true, keyParameters);
signer.BlockUpdate(message, 0, message.Length);
var signature = signer.GenerateSignature();
This seems to work as expected but I'm unable to get the recovery ID.
Here's an example of how another library does this.
https://github.com/EOSIO/eosjs-ecc/blob/a806b93fbbccec8d38c0c02998d204ff2040a6ae/src/ecdsa.js#L199
Can someone explain how I can do that same using BouncyCastle please?
This was another post that seemed helpful, but wasn't specific to how to do this with BouncyCastle https://bitcoin.stackexchange.com/questions/83035/how-to-determine-first-byte-recovery-id-for-signatures-message-signing
CertificateI have a Certificate
This is the text i have to verify:
B5080F731EE89EC82FD2E8B22E9_I_CANNOT_SHOW_THE_REAL_TEXT
This is the signed:
MIIBUwYJKoZIhvcNAQcCoIIBRDCCAUACAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAR8wggEbAgEBMG8wZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwMjEyMzYwMQwwCgYDVQQDEwNFMTUCByASBQYIEQgwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE4MDYyNzE5MzcyNVowIwYJKoZIhvcNAQkEMRYEFDgpp0877pKaChyIGVw5sPeD0W03MAkGByqGSM44BAMEMDAuAhUA4PH8bdBPHHtuPHvhJxjei%2BFrJYUCFQCnZ6IABDiRlctS9E9N3IQK60JLIg%3D%3D
CanĀ“t find a way to do verify the signature with c#. When i use the "normal" DSACryptoServiceProvider I always get the error saying the signature size should be 40 bytes.
I just need to know were to go. wath to use
I know is DSA.
I know the signature is around 500bytes
this is the code i'm trying:
DSACryptoServiceProvider csp = (DSACryptoServiceProvider)CurrentCer.csp.PublicKey.Key;
SHA1Managed sha1 = new SHA1Managed();
byte[] data = Encoding.UTF8.GetBytes(ToSign);
byte[] hash = sha1.ComputeHash(data);
var base64EncodedBytes = System.Convert.FromBase64String(signature);
result = csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), base64EncodedBytes);
DSASignatureDeformatter verifier = new DSASignatureDeformatter(csp);
verifier.SetHashAlgorithm("SHA1");
bool valid = verifier.VerifySignature(hash, base64EncodedBytes);
Your data isn't a signature, per se. It's a query-string-encoded base64-encoded representation of a CMS Signed-Data with detached content, and it happens to have been signed with DSA.
str = Uri.UnescapeDataString(str);
byte[] signatureMessage = Convert.FromBase64String(str);
ContentInfo content = new ContentInfo(yourDataHere);
SignedCms signedCms = new SignedCms(content, detached: true);
signedCms.Decode(signatureMessage);
SignerInfoCollection signers = signedCms.SignerInfos;
if (signers.Count != 1 || signers[0].Certificate != null)
{
// Reject it, this isn't what you're looking for.
// At least, based on the sample you gave.
//
// You could, for Count == 1, accept Certificate == null or
// Certificate.RawData.SequenceEqual(CurrentCer.RawData),
// if you're so inclined.
}
// This throws if the signature doesn't check out.
signedCms.CheckSignature(new X509Certificate2Collection(CurrentCer), verifySignatureOnly: true);
I am trying to create a Apple wallet passes in my system, after reading Different S/MIME signature between OpenSSL and C# and Apple Passbook coupons from C#, the system can create .pkasss automatically now.
And my problem is signature cannot create successfully in actual. If I using iPhone and try to open the .pkpass file, it can't be open!! I find out that is the problem is coming form signature, if I using mac to create a signature in terminal, it create a 3326bytes size signature; my code only can create a 3002 bytes file, which means the signature must be miss something.
Does Mac OS X method have a big difference between Windows OS method?
Has anyone faced this problem before? Does anyone know why the signatures are different?
Does anyone know how t fix it?
This is my source code:
var cert = new X509Certificate2(assetsFolder + p12File, p12Password);
var buffer = File.ReadAllBytes(Path.Combine(assetsFolder, "manifest.json"));
var cont = new ContentInfo(buffer);
var cms = new SignedCms(cont, true);
var signer = new CmsSigner(cert)
{
IncludeOption = X509IncludeOption.ExcludeRoot,
SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber,
};
cms.ComputeSignature(signer, true);
var myCmsMessage = cms.Encode();
File.WriteAllBytes(Path.Combine(assetsFolder, "signature"), myCmsMessage);
Big Thanks!!!
----------------------------------UPDATE---------------------------------
I found the ans of signature!!!
The setting of OID and SignerIdentifierType will affert the signature
Here is my solution:
byte[] buffer = File.ReadAllBytes(Path.Combine(assetsFolder, "manifest.json"));
X509Certificate2 cert = new X509Certificate2(assetsFolder + p12File, p12Password);
var oid = new Oid("1.2.840.113549.1.7.2");
ContentInfo contentInfo = new ContentInfo(oid, buffer);
SignedCms signedCms = new SignedCms(contentInfo, true);
var cmsSigner = new CmsSigner(cert);
cmsSigner.IncludeOption = X509IncludeOption.ExcludeRoot;
cmsSigner.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.Now));
cmsSigner.SignerIdentifierType = SubjectIdentifierType.SubjectKeyIdentifier;
signedCms.ComputeSignature(cmsSigner);
byte[] myCmsMessage = signedCms.Encode();
return myCmsMessage;
I found this post related to pkcs#7 decrypting which suggest that there is no out of the box way to decrypt a signed pkcs#7 file. Decrypting PKCS#7 encrypted data in C#
However, I also saw this post and I managed to validate using the SignedCms class. http://blogs.msdn.com/b/shawnfa/archive/2006/02/27/539990.aspx
At the end of the post though, extracting the data using cms.ContentInfo.Content seems to return the signed file (.zip.p7) instead of the actual content (.zip). Am I missing something here? Using bouncy castle, I was able to get the actual data but would rather not use a third party if it's not necessary.
static void Main(string[] args)
{
var encodedFile = File.ReadAllBytes(InPath);
var signedData = new SignedCms();
signedData.Decode(encodedFile);
signedData.CheckSignature(true);
if (!Verify(signedData))
throw new Exception("No valid cert was found");
var trueContent = new CmsSignedData(File.ReadAllBytes(InPath)).SignedContent;
using (var str = new MemoryStream())
{
trueContent.Write(str);
var zip = new ZipArchive(str, ZipArchiveMode.Read);
zip.ExtractToDirectory(OutPath);
}
//using (var str = new MemoryStream(signedData.ContentInfo.Content))
//{
// var zip = new ZipArchive(str, ZipArchiveMode.Read);
// zip.ExtractToDirectory(OutPath);
//}
}
static bool Verify(SignedCms signedData)
{
var myCetificates = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myCetificates.Open(OpenFlags.ReadOnly);
var certs = signedData.Certificates;
return (from X509Certificate2 cert in certs
select myCetificates.Certificates.Cast<X509Certificate2>()
.Any(crt => crt.Thumbprint == cert.Thumbprint))
.Any();
}
UPDATE: Will get back with the base64 sample file. Need to come up with one that doesn't contain sensitive information.
UPDATE: Here is the base 64 version of a file I can extract using bouncy castle but not using the ContentInfo.Content property. I've added as a comment on the code how I would extract SignedCms directly.
MIIFfQYJKoZIhvcNAQcCoIIFbjCCBWoCAQExCzAJBgUrDgMCGgUAMIHOBgEAoIHIBIHFUEsDBBQAAAAIAGRuWEggPN74JwAAADsAAAAMAAAAdGVzdGRhdGEudHh0bcixDQAgCEXB3sQd/gq6EVFaLHz7hwHgysM/uobpvMCDOUppdbkTUEsBAj8AFAAAAAgAZG5YSCA83vgnAAAAOwAAAAwAJAAAAAAAAAAgAAAAAAAAAHRlc3RkYXRhLnR4dAoAIAAAAAAAAQAYAOAo0XGdbtEBktqpaZ1u0QGS2qlpnW7RAVBLBQYAAAAAAQABAF4AAABRAAAAAACgggL7MIIC9zCCAd+gAwIBAgIQN3SCtKd9Hp1BDqeyqVr+tjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwdmb28uYmFyMB4XDTE2MDIyNDAwNDg0MFoXDTM5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJcGtjczdzaWduMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh5KDyFhPcxueQ1vJ0yQpcAyrSHLKw/Y2K0qhZfa7W3A6q33/i8VLl0XOFCCJs+iwcJcC+iCOIw+fFkRUEj9d7Z1sKwBCcZMolkZtNvtdXOgphV6R3g6/QNZgiQ3FFqHgp7+5OAdtBEsfsoowOClnVqZAmXnXW3Pl6Lsx0wxI8A7huytqboKRqrbRz02xO9rR1Ism0g5uQBtB2rpqGQk6/1ti/UYCp9fx7pxvWhe+a+oNIq7+ijAHPNLC+bwQTGd3LhwkzMSdONpY/utdbqCqToq/IbQ7KM0NRExZL/egPCsyJ2GGBQOVCveKkzdsW5V8p2XljcI5Sq7V8lVtqR3unwIDAQABo0cwRTBDBgNVHQEEPDA6gBBZ/6xjvqs3BLMBnQj5XmOJoRQwEjEQMA4GA1UEAxMHZm9vLmJhcoIQCiUdhpq5qrlA3FTAf3hpsTANBgkqhkiG9w0BAQsFAAOCAQEAcYl//1mzJa62K5uR+8CrpsrPWHEJ1H8l25CUQGL3u4g+ANOvJsJR6nryo4us9nI7XPocJNnFCoj26qfNmWgIF5giGkQpU2gRV5bPvYc6nPj4jZaQ7RcxJ4FT1BN/3ue7NLREodO/E1J2YWKE3uOLreBikn5B6tPKPEzA8XTjVB0ZZzfu7LMvsltB2fcaEbsifVCt4hlbtWlgFuNCbidIRWMpg8NdwcWydR1C7kuKGh1LJDG0v3ZPRgytkie8l/9zqvki4wt/kWXmDwba0lCWoyrfyahGMq5u2cqLG45pk/+1L89nw3BfR1U+5b786iXgNXKmYRWchwMQQ9r1xEa5FTGCAYYwggGCAgEBMCYwEjEQMA4GA1UEAxMHZm9vLmJhcgIQN3SCtKd9Hp1BDqeyqVr+tjAJBgUrDgMCGgUAoDcwEAYJKoZIhvcNAQkDMQMGAQAwIwYJKoZIhvcNAQkEMRYEFGmRdgvd3g6DeMqXK0QfUmJq7UnFMA0GCSqGSIb3DQEBAQUABIIBAEKdfeAfyc5TAei/GWW6Ns6aAvOrVXqNkkOJessd9P2ZYSxG4CTOo300jea7o2DYruiC4FJnSPqH7NoI0Q8EAod/E7HevZnrUq2Rtga4hSZSJfgnQuJqrOJksWfysRqt86cfwQYqmlSd94e7CgmT293rGTbG8SdXxRA8qi2J+2OULVSBFi3Z1x0hQlf31ioVBl5WMchsM8ri/q9IBBwFGqdEKVqxcmLkEtVv3czCq1z6rqkXkDk/qZ7qlhDzAqn8uguoXqhOR075Hv3Qnz6j1R+220aCOq5CmZIzdk8o8arEA9siXUASjbQpzULpG5fAenlCrgCnAXBkzkJKsBaTbYY=
I'm trying to sign a manifest file to be used in Passbook using c#. my code was doing fine until they released GM of iOS6. in this seed they want the signature to include the intemidiate certificate. Here's my code:
var dataToSign = System.IO.File.ReadAllBytes(filePathToSign);
ContentInfo contentInfo = new ContentInfo(new Oid("1.2.840.113549.1.7.2"), dataToSign);
var signerCert = new X509Certificate2(signerPfxCertPath, signerPfxCertPassword);
var signedCms = new SignedCms(contentInfo, true);
var signer = new CmsSigner(signerCert);
signer.IncludeOption = X509IncludeOption.ExcludeRoot;
signedCms.ComputeSignature(signer);
var myCmsMessage = signedCms.Encode();
return myCmsMessage;
I have the certificat einstalled on my machine but it doesn't work. any ideas what I'm missing?
As mentioned on comments (Thanks to Rudi):
Blockquote look here or here