private static unsafe SafeLocalAllocHandle EncodePublicKey(PublicKey key) { SafeLocalAllocHandle publicKeyInfo = SafeLocalAllocHandle.InvalidHandle; CAPI.CERT_PUBLIC_KEY_INFO2 *pPublicKeyInfo = null; string objId = key.Oid.Value; byte[] encodedParameters = key.EncodedParameters.RawData; byte[] encodedKeyValue = key.EncodedKeyValue.RawData; uint cbPublicKeyInfo = (uint)(Marshal.SizeOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO2)) + X509Utils.AlignedLength((uint)(objId.Length + 1)) + X509Utils.AlignedLength((uint)encodedParameters.Length) + encodedKeyValue.Length); publicKeyInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbPublicKeyInfo)); pPublicKeyInfo = (CAPI.CERT_PUBLIC_KEY_INFO2 *)publicKeyInfo.DangerousGetHandle(); IntPtr pszObjId = new IntPtr((long)pPublicKeyInfo + Marshal.SizeOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO2))); IntPtr pbParameters = new IntPtr((long)pszObjId + X509Utils.AlignedLength(((uint)(objId.Length + 1)))); IntPtr pbPublicKey = new IntPtr((long)pbParameters + X509Utils.AlignedLength((uint)encodedParameters.Length)); pPublicKeyInfo->Algorithm.pszObjId = pszObjId; byte[] szObjId = new byte[objId.Length + 1]; Encoding.ASCII.GetBytes(objId, 0, objId.Length, szObjId, 0); Marshal.Copy(szObjId, 0, pszObjId, szObjId.Length); if (encodedParameters.Length > 0) { pPublicKeyInfo->Algorithm.Parameters.cbData = (uint)encodedParameters.Length; pPublicKeyInfo->Algorithm.Parameters.pbData = pbParameters; Marshal.Copy(encodedParameters, 0, pbParameters, encodedParameters.Length); } pPublicKeyInfo->PublicKey.cbData = (uint)encodedKeyValue.Length; pPublicKeyInfo->PublicKey.pbData = pbPublicKey; Marshal.Copy(encodedKeyValue, 0, pbPublicKey, encodedKeyValue.Length); return(publicKeyInfo); }