/// <summary> /// To be called after the TPM has returned the addedTo part of the certificate and the signature. Assembles /// partialCert, addedTo, and the signature to form an actual X.509 certificate encapsulated in a Bouncy Castle /// X509Certificate /// </summary> /// <param name="partialCert"></param> /// <param name="addedToCertificate"></param> /// <param name="signature"></param> /// <returns></returns> internal static X509Certificate AssembleCertificate( PartialCertificate partialCert, AddedToCertificate addedToCertificate, byte[] signatureBytes) { Debug.Assert(addedToCertificate.Version.ToString() == "2"); var signature = new DerBitString(signatureBytes); var sigAlgID = partialCert.SigAlgID ?? addedToCertificate.SigAlgID; // Assemble TBS. Start with a vector which we will later convert to a sequence Asn1EncodableVector tbsContents = new Asn1EncodableVector(); tbsContents.Add(new DerTaggedObject(0, new DerInteger(BigInteger.ValueOf(2)))); tbsContents.Add(addedToCertificate.SerialNumber); tbsContents.Add(sigAlgID); tbsContents.Add(partialCert.Issuer); tbsContents.Add(new CertificateValidity(partialCert.NotBefore, partialCert.NotAfter)); tbsContents.Add(partialCert.Subject); tbsContents.Add(addedToCertificate.SubjectPublicKeyInfo); // Add optional components if (partialCert.IssuerUniqueId != null) { tbsContents.Add(new DerTaggedObject(false, 1, new DerBitString(partialCert.IssuerUniqueId))); } if (partialCert.SubjectUniqueId != null) { tbsContents.Add(new DerTaggedObject(false, 2, new DerBitString(partialCert.SubjectUniqueId))); } if (partialCert.Extensions != null) { tbsContents.Add(new DerTaggedObject(3, partialCert.Extensions.ToAsn1Object())); } // Convert the vector to an ASN SEQUENCE var tbsCertificate = new DerSequence(tbsContents); // assemble the certificate. Start with the components as a vector Asn1EncodableVector certContents = new Asn1EncodableVector(); certContents.Add(tbsCertificate); certContents.Add(sigAlgID); certContents.Add(signature); // Convert to a SEQUENCE. certSequence will contain the DER encoded certificate var certSequence = new DerSequence(certContents); // Convert to a first-class BC X509Certificate var certBytes = certSequence.GetEncoded(); var cert = new X509CertificateParser().ReadCertificate(certSequence.GetEncoded()); // and return it return(cert); }
public static byte[] encodeSM2CipherToDER(byte[] cipher) { int startPos = 1; int curveLength = 32; int digestLength = 32; byte[] c1x = new byte[curveLength]; Buffer.BlockCopy(cipher, startPos, c1x, 0, c1x.Length); startPos += c1x.Length; byte[] c1y = new byte[curveLength]; Buffer.BlockCopy(cipher, startPos, c1y, 0, c1y.Length); startPos += c1y.Length; byte[] c2 = new byte[cipher.Length - c1x.Length - c1y.Length - 1 - digestLength]; Buffer.BlockCopy(cipher, startPos, c2, 0, c2.Length); startPos += c2.Length; byte[] c3 = new byte[digestLength]; Buffer.BlockCopy(cipher, startPos, c3, 0, c3.Length); Asn1Encodable[] arr = new Asn1Encodable[4]; arr[0] = new DerInteger(new BigInteger(1, c1x)); // arr[1] = new DerInteger(new BigInteger(1, c1y)); // arr[2] = new DerOctetString(c3); arr[3] = new DerOctetString(c2); DerSequence ds = new DerSequence(arr); return(ds.GetEncoded(Asn1Encodable.Der)); }
/// <summary> /// SM2签名Hard转soft /// </summary> /// <param name="hardSign"></param> /// <returns></returns> public static String SM2SignHardToSoft(String hardSign) { byte[] bytes = hardSign.hexToByte(); byte[] r = new byte[bytes.Length / 2]; byte[] s = new byte[bytes.Length / 2]; System.Array.Copy(bytes, 0, r, 0, bytes.Length / 2); System.Array.Copy(bytes, bytes.Length / 2, s, 0, bytes.Length / 2); var d_r = new DerInteger(SM2CryptoServiceProvider.byteConvertInteger(r)); var d_s = new DerInteger(SM2CryptoServiceProvider.byteConvertInteger(s)); var v2 = new Asn1EncodableVector(); v2.Add(d_r); v2.Add(d_s); var sign = new DerSequence(v2); String result = null; try { result = sign.GetEncoded().ByteArrayToHex(); } catch (IOException e) { //e.printStackTrace(); throw (e); } //SM2加密机转软加密编码格式 //return SM2SignHardKeyHead+hardSign.substring(0, hardSign.Length()/2)+SM2SignHardKeyMid+hardSign.substring(hardSign.Length()/2); return(result); }
private string GenerateX509Cert(string publicKey, string x509Subject) { Asn1Sequence asn1Sequence = null; using (var reader = new StringReader(publicKey)) { // Read the RSA public key from the input string. var pemReader = new PemReader(reader); var pemObject = pemReader.ReadPemObject(); asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(pemObject.Content); } // Generate a TBS certificate. We use placeholder-like values since // the consumer of this certificate should only use the subject // public key info. var tbsCertGen = new V3TbsCertificateGenerator(); tbsCertGen.SetSerialNumber(new DerInteger(1)); var signatureAlgId = new AlgorithmIdentifier(PkcsObjectIdentifiers.Sha1WithRsaEncryption, DerNull.Instance); tbsCertGen.SetSignature(signatureAlgId); tbsCertGen.SetIssuer(new X509Name("CN=Root Agency")); var dateTimeNow = DateTime.Now; tbsCertGen.SetStartDate(new Time(dateTimeNow.AddMinutes(-10))); tbsCertGen.SetEndDate(new Time(dateTimeNow.AddYears(1))); // Openssh key doesn`t have any start/end date, this is to satisfy RDFE tbsCertGen.SetSubject(new X509Name(x509Subject)); tbsCertGen.SetSubjectPublicKeyInfo(new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), asn1Sequence)); var tbsCert = tbsCertGen.GenerateTbsCertificate(); // Per RFC 3280, the layout of an X.509 v3 certificate looks like: // Certificate ::= SEQUENCE { // tbsCertificate TBSCertificate, // signatureAlgorithm AlgorithmIdentifier, // signatureValue BIT STRING // } // Since we don't have access to the private key, we cannot create // a signature for the TBS. However, a valid certificate requires // a bit string for the signature value, so we use a 0-byte array // in its place. Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(tbsCert); v.Add(signatureAlgId); v.Add(new DerBitString(new byte[0])); var derSequence = new DerSequence(v); // Output the DER-encoded X509 certificate. var sb = new StringBuilder(); using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture)) { var pemWriter = new PemWriter(writer); pemWriter.WriteObject(new PemObject("CERTIFICATE", derSequence.GetEncoded())); } return(sb.ToString()); }
private string GeneratePkcs1PublicKeyFromRsaEncryptedOpenSshPublicKey(string content) { List <byte[]> data = this.GetOpenSshPublicKeyInBinary(content); if (data.Count != 3) { throw new InvalidOperationException("Given OpenSSH key body is invalid."); } //// RFC 3447 (PKCS #1) //// 3.1 RSA public key //// For the purposes of this document, an RSA public key consists of two //// components: //// n the RSA modulus, a positive integer //// e the RSA public exponent, a positive integer //// A recommended syntax for interchanging RSA public keys between //// implementations is given in Appendix A.1.1; an implementation's //// internal representation may differ. //// A.1.1 RSA public key syntax //// An RSA public key should be represented with the ASN.1 type //// RSAPublicKey: //// RSAPublicKey ::= SEQUENCE { //// modulus INTEGER, -- n //// publicExponent INTEGER -- e //// } //// The fields of type RSAPublicKey have the following meanings: //// * modulus is the RSA modulus n. //// * publicExponent is the RSA public exponent e. //// RFC 4251: Strings are also used to store text. In that case, US-ASCII is //// used for internal names, and ISO-10646 UTF-8 for text that might be displayed to the user. string algorithmName = Encoding.UTF8.GetString(data[0]); if (!"ssh-rsa".Equals(algorithmName, StringComparison.Ordinal)) { throw new InvalidOperationException("Invalid OpenSSH key body, expected 'ssh-rsa' encrypted."); } var publicExponent = new DerInteger(data[1]); var modulus = new DerInteger(data[2]); var sequence = new DerSequence(new Asn1Encodable[] { modulus, publicExponent }); // Generate DER-encoded public key StringBuilder sb = new StringBuilder(); using (var sw = new StringWriter(sb, CultureInfo.InvariantCulture)) { var pemWriter = new Org.BouncyCastle.Utilities.IO.Pem.PemWriter(sw); pemWriter.WriteObject(new PemObject("RSA PUBLIC KEY", sequence.GetEncoded())); } return(sb.ToString()); }
private static byte[] EncodePublicKey(PublicKey publicKey) { var rawKey = publicKey.EncodedKeyValue.RawData; var sequence = new DerSequence( new DerSequence(new DerObjectIdentifier(publicKey.Oid.Value), DerNull.Instance), new DerBitString(rawKey) ); return(sequence.GetEncoded()); }
public byte[] SHA256_DER(byte[] message) { Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(new DerObjectIdentifier("2.16.840.1.101.3.4.2.1")); v.Add(new DerOctetString(message)); var s = new DerSequence(v); DumpASN(s); return(s.GetEncoded()); }
public byte[] KI_KeyBlock(byte[] KI, byte[] TCUID, byte[] DTS, byte[] RNsp, byte[] user_data) { Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(new DerOctetString(KI)); v.Add(new DerOctetString(TCUID)); v.Add(new DerOctetString(DTS)); v.Add(new DerOctetString(RNsp)); v.Add(new DerOctetString(user_data)); var s = new DerSequence(v); DumpASN(s); return(s.GetEncoded()); }
/** * 私钥签名 * 使用SM3进行对明文数据计算一个摘要值 * @param privatekey 私钥 * @param sourceData 明文数据 * @return 签名后的值 * @throws Exception */ public static SM2SignVO Sign2SM2(byte[] privatekey, byte[] sourceData) { SM2SignVO sm2SignVO = new SM2SignVO(); sm2SignVO.setSm2_type("sign"); var factory = SM2CryptoServiceProvider.Instance; BigInteger userD = new BigInteger(privatekey); //System.out.println("userD:"+userD.toString(16)); sm2SignVO.setSm2_userd(userD.ToByteArray().ToHexString()); ECPoint userKey = factory.ecc_point_g.Multiply(userD); //System.out.println("椭圆曲线点X: "+ userKey.getXCoord().toBigInteger().toString(16)); //System.out.println("椭圆曲线点Y: "+ userKey.getYCoord().toBigInteger().toString(16)); SM3Digest sm3Digest = new SM3Digest(); byte[] z = factory.Sm2GetZ(USER_ID.GetBytes(), userKey); //System.out.println("SM3摘要Z: " + Util.getHexString(z)); //System.out.println("被加密数据的16进制: " + Util.getHexString(sourceData)); sm2SignVO.setSm3_z(z.ToHexString()); sm2SignVO.setSign_express(sourceData.ToHexString()); sm3Digest.update(z, 0, z.Length); sm3Digest.update(sourceData, 0, sourceData.Length); byte[] md = new byte[32]; sm3Digest.doFinal(md, 0); //System.out.println("SM3摘要值: " + Util.getHexString(md)); sm2SignVO.setSm3_digest(md.ToHexString()); SM2Result sm2Result = new SM2Result(); factory.sm2Sign(md, userD, userKey, sm2Result); //System.out.println("r: " + sm2Result.r.toString(16)); //System.out.println("s: " + sm2Result.s.toString(16)); sm2SignVO.setSign_r(sm2Result.r.ToByteArray().ToHexString()); sm2SignVO.setSign_s(sm2Result.s.ToByteArray().ToHexString()); var d_r = new DerInteger(sm2Result.r); var d_s = new DerInteger(sm2Result.s); var v2 = new Asn1EncodableVector(); v2.Add(d_r); v2.Add(d_s); var sign = new DerSequence(v2); String result = sign.GetEncoded().ByteArrayToHex(); sm2SignVO.setSm2_sign(result); return(sm2SignVO); }
/// <summary> /// Returns the extension in raw data /// </summary> /// <returns></returns> public byte[] Export() { if (string.IsNullOrEmpty(CertificateTemplate)) { throw new ArgumentException(); } var param = new List <Asn1Encodable>(); param.Add(new DerBmpString(CertificateTemplate)); var seq = new DerSequence(param.ToArray()); return(seq.GetEncoded()); }
private static byte[] BuildOCSPResponse(byte[] BasicOCSPResponse) { DerOctetString doctet = new DerOctetString(BasicOCSPResponse); Asn1EncodableVector v2 = new Asn1EncodableVector(); v2.Add(OcspObjectIdentifiers.PkixOcspBasic); v2.Add(doctet); DerEnumerated den = new DerEnumerated(0); Asn1EncodableVector v3 = new Asn1EncodableVector(); v3.Add(den); v3.Add(new DerTaggedObject(true, 0, new DerSequence(v2))); DerSequence seq = new DerSequence(v3); return(seq.GetEncoded()); }
public String getEncoded() { //TextWriter textWriter = new StringWriter(); //PemWriter pemWriter = new PemWriter(textWriter); //pemWriter.WriteObject(pubKey); //pemWriter.Writer.Flush(); //String pemString = textWriter.ToString(); // I am forced to use this type of PEM coding, although I am not sure if it is right. // The previous code from Bouncy Castle, although technicaly correct, doesn't output the same coding od Dart code. DerSequence pubKeySequence = new DerSequence(new DerInteger(pubKey.Modulus), new DerInteger(pubKey.Exponent)); string dataBase64 = Convert.ToBase64String(pubKeySequence.GetEncoded()); string pemString = $"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A{dataBase64}\n-----END PUBLIC KEY-----"; return(pemString); //*** 20200524 RC: Encoding to be checked against rel. 2.1 Dart! }
/// <summary> /// Returns the extension in raw data /// </summary> /// <returns></returns> public byte[] Export() { if (Id == null) { throw new ArgumentException(); } var param = new List <Asn1Encodable>(); param.Add(new DerObjectIdentifier(Id.Value)); param.Add(new DerInteger(MajorVersion)); param.Add(new DerInteger(MinorVersion)); var seq = new DerSequence(param.ToArray()); return(seq.GetEncoded()); }
public void TestFormatSignature() { var random = new Random(); var dsa_key = new SshKey(SshVersion.SSH2, new DsaPublicKeyParameters( new BigInteger("1"), new DsaParameters(new BigInteger("2"), new BigInteger("3"), new BigInteger("4")))); // test that dsa signature works when values are not full 20 bytes. byte[] r_bytes = new byte[19]; byte[] s_bytes = new byte[19]; random.NextBytes(r_bytes); random.NextBytes(s_bytes); var r = new DerInteger(r_bytes); var s = new DerInteger(s_bytes); var sequence = new DerSequence(r, s); var signature = dsa_key.FormatSignature(sequence.GetEncoded()); Assert.That(signature.Count(), Is.EqualTo(40)); }
public static bool verifySign(string signature, byte[] origdata, ICipherParameters pubkey) { var dsa = SignerUtilities.GetSigner(ECDSA); dsa.Init(false, pubkey); dsa.BlockUpdate(origdata, 0, origdata.Length); BigInteger r = new BigInteger(signature.Substring(0, 64), 16); BigInteger s = new BigInteger(signature.Substring(64, 64), 16); Asn1EncodableVector vec = new Asn1EncodableVector(); vec.Add(new DerInteger(r)); vec.Add(new DerInteger(s)); Asn1Sequence seq = new DerSequence(vec); byte[] sign = seq.GetEncoded(); bool result = dsa.VerifySignature(sign); return(result); }
/// <summary> /// Signature /// </summary> /// <param name="data"></param> /// <param name="userId"></param> /// <param name="publicKey"></param> /// <returns></returns> public static byte[] Signature2(byte[] data, byte[] userId, byte[] publicKey) { if (publicKey is null || publicKey.Length == 0) { return(null); } if (data is null || data.Length == 0) { return(null); } SM2Core sm2 = SM2Core.Instance; BigInteger userD = new BigInteger(Hex.Decode(publicKey)); ECPoint userKey = sm2.ecc_point_g.Multiply(userD); SM2Core.SM2_SM3Digest sm3 = new SM2Core.SM2_SM3Digest(); byte[] z = sm2.Sm2GetZ(userId, userKey); sm3.BlockUpdate(z, 0, z.Length); sm3.BlockUpdate(data, 0, data.Length); byte[] md = new byte[32]; sm3.DoFinal(md, 0); SM2Result sm2Result = new SM2Result(); sm2.Sm2Sign(md, userD, userKey, sm2Result); DerInteger d_r = new DerInteger(sm2Result.r); DerInteger d_s = new DerInteger(sm2Result.s); Asn1EncodableVector v2 = new Asn1EncodableVector(); v2.Add(d_r); v2.Add(d_s); DerSequence sign = new DerSequence(v2); byte[] signdata = sign.GetEncoded(); return(signdata); }
private byte[] SignBytesDsa(byte[] byteArray, string pathToPrivateKeyPemFile) { // Create a digest of nonce + cnonce // This only seems to work with SHA1 (SHA256 gives us a 401 error) var sha = SHA1.Create(); var digest = sha.ComputeHash(byteArray); // Read DSA key DsaKeyParameters keyParameters; using (var fileStream = System.IO.File.OpenText(pathToPrivateKeyPemFile)) { var pemReader = new PemReader(fileStream); keyParameters = (DsaKeyParameters)pemReader.ReadObject(); } // Create DSA signer DsaSigner sig = new DsaSigner(); sig.Init(true, keyParameters); // Digitally sign the digest with our private key // The corresponding public key is in our admin handle on the server var signature = sig.GenerateSignature(digest); // Signature bytes from a DSA key need to be DER-encoded // This signature is in two parts (r and s) DerSequence seq = new DerSequence(new Asn1Encodable[2] { new DerInteger(signature[0]), new DerInteger(signature[1]) }); var encode = seq.GetEncoded(); var derEncode = seq.GetDerEncoded(); return(seq.GetDerEncoded()); }
/// <summary> /// Write myself to the given stream /// </summary> public void WriteTo(Stream stream, out string md5FingerPrint, out string sha1FingerPrint) { X509Certificate[] cert; AsymmetricKeyEntry privateKey; LoadPfx(out cert, out privateKey); var certsVector = new Asn1EncodableVector(); md5FingerPrint = null; sha1FingerPrint = null; foreach (var c in cert) { var certStream = new MemoryStream(c.GetEncoded()); var certStruct = X509CertificateStructure.GetInstance(new Asn1InputStream(certStream).ReadObject()); certsVector.Add(certStruct); if (md5FingerPrint == null) { var certData = certStream.ToArray(); md5FingerPrint = CreateFingerprint(new MD5Digest(), certData); } if (sha1FingerPrint == null) { var certData = certStream.ToArray(); sha1FingerPrint = CreateFingerprint(new Sha1Digest(), certData); } } var encryptedSignature = GetSignature(signature, privateKey.Key); var signerInfo = new SignerInfo( new DerInteger(1), new IssuerAndSerialNumber(cert[0].IssuerDN, cert[0].SerialNumber), new AlgorithmIdentifier(Oids.SHA1, DerNull.Instance), null, new AlgorithmIdentifier(Oids.RSA, DerNull.Instance), new DerOctetString(encryptedSignature), null); var pkcs7 = new SignedData( new DerInteger(1), new DerSet(new AlgorithmIdentifier(Oids.SHA1, DerNull.Instance)), new ContentInfo(new DerObjectIdentifier(Oids.data), null), new DerSet(certsVector), null, new DerSet(signerInfo)); //var signedData = new ContentInfo(new DERObjectIdentifier(Oids.signedData), pkcs7); var v = new Asn1EncodableVector(); v.Add(new DerObjectIdentifier(Oids.signedData)); v.Add(new DerTaggedObject(0, pkcs7)); var signedData = new DerSequence(v); // Save var data = signedData.GetEncoded(); stream.Write(data, 0, data.Length); }
public static CngKey Import(Byte[] blob, Int32 offset = 0) { Boolean isPrivateKey = false; Byte keyLength = 0; Byte[] keyCurveX = null, keyCurveY = null, keyScalar = null; Byte[] inBlob = blob; // Apply offset to incoming data. if (offset > 0) { var blobLength = blob.Length - (offset); inBlob = new Byte[blobLength]; Array.Copy(blob, offset, inBlob, 0, blobLength); } System.IO.File.WriteAllBytes("Key.key", inBlob); DerSequence der = (DerSequence)DerSequence.FromByteArray(inBlob); try { /*to read directly*/ isPrivateKey = ((DerBitString)der[0]).IntValue != 0; } catch { der = (DerSequence)DerSequence.FromByteArray(((DerOctetString)der[1]).GetOctets()); System.IO.File.WriteAllBytes("KeyDer.key", der.GetEncoded()); } // Read Data from Key. isPrivateKey = ((DerBitString)der[0]).IntValue != 0; keyLength = (Byte)((DerInteger)der[1]).PositiveValue.IntValue; keyCurveX = ((DerInteger)der[2]).PositiveValue.ToByteArrayUnsigned(); keyCurveY = ((DerInteger)der[3]).PositiveValue.ToByteArrayUnsigned(); if (isPrivateKey) { keyScalar = ((DerInteger)der[4]).PositiveValue.ToByteArrayUnsigned(); } // Validate data. if (keyLength == 0) { throw new IndexOutOfRangeException("Length of key is 0."); } if (keyCurveX == null || keyCurveY == null) { throw new IndexOutOfRangeException("Key Curve is not set."); } // Construct a readable key out of this data. Byte[] newBlob = new Byte[8 + (keyLength * (2 + (isPrivateKey ? 1 : 0)))]; // Write Key Header for ECCPrivateBlob or ECCPublicBlob. newBlob[0] = (Byte)0x45; // E newBlob[1] = (Byte)0x43; // C newBlob[2] = (Byte)0x4B; // K newBlob[3] = (Byte)(keyLength == 32 ? 0x31 : (keyLength == 48 ? 0x33 : (keyLength == 64 ? 0x35 : 0x00))); newBlob[3] += (Byte)(isPrivateKey ? 0x01 : 0x00); newBlob[4] = (Byte)keyLength; Array.Copy(keyCurveX, 0, newBlob, 8, keyCurveX.Length); Array.Copy(keyCurveY, 0, newBlob, 8 + keyLength, keyCurveY.Length); if (isPrivateKey) { Array.Copy(keyScalar, 0, newBlob, 8 + keyLength * 2, keyScalar.Length); } // Now return a valid Key. if (isPrivateKey) { return(CngKey.Import(newBlob, CngKeyBlobFormat.EccPrivateBlob)); } else { return(CngKey.Import(newBlob, CngKeyBlobFormat.EccPublicBlob)); } }