是否可以通过编程方式将在Visual Studios中创建的x509证书上传到Azure应用程序清单中?
我遵循this post创建了x509证书:
public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey)
{
const int keyStrength = 2048;
//generate random numbers
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random);
//the certificate generator
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
//serial number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random );
certificateGenerator.SetSerialNumber(serialNumber);
// Issuer and Subject Name
X509Name subjectDN = new X509Name("CN="+ subjectName);
X509Name issuerDN = new X509Name("CN="+issuerName);
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
//valid For
DateTime notBefore = DateTime.Now;
DateTime notAfter = notBefore.AddYears(2);
certificateGenerator.SetNotBefore(notBefore);
certificateGenerator.SetNotAfter(notAfter);
//Subject Public Key
AsymmetricCipherKeyPair subjectKeyPair;
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
var keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
//selfSign certificate
Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
var dotNetPrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters) subjectKeyPair.Private);
//merge into X509Certificate2
X509Certificate2 x509 = new X509Certificate2(DotNetUtilities.ToX509Certificate(certificate));
x509.PrivateKey = dotNetPrivateKey;
x509.FriendlyName = subjectName;
return x509;
}
public static X509Certificate2 CreateCertificateAuthorityCertificate(string subjectName, out AsymmetricKeyParameter CaPrivateKey)
{
const int keyStrength = 2048;
//generate Random Numbers
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
//The Certificate Generator
X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
//Serial Number
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
certificateGenerator.SetSerialNumber(serialNumber);
//Issuer and Subject Name
X509Name subjectDN = new X509Name("CN="+subjectName);
X509Name issuerDN = subjectDN;
certificateGenerator.SetIssuerDN(issuerDN);
certificateGenerator.SetSubjectDN(subjectDN);
//valid For
DateTime notBefore = DateTime.Now;
DateTime notAfter = notBefore.AddYears(2);
certificateGenerator.SetNotBefore(notBefore);
certificateGenerator.SetNotAfter(notAfter);
//subject Public Key
AsymmetricCipherKeyPair subjectKeyPair;
KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
subjectKeyPair = keyPairGenerator.GenerateKeyPair();
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
//generating the certificate
AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;
ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);
//selfSign Certificate
Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
X509Certificate2 x509 = new X509Certificate2(certificate.GetEncoded());
x509.FriendlyName = subjectName;
CaPrivateKey = issuerKeyPair.Private;
return x509;
}
public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
{
var cspParams = new CspParameters()
{
KeyContainerName = Guid.NewGuid().ToString(),
KeyNumber = (int)KeyNumber.Exchange,
Flags = CspProviderFlags.UseMachineKeyStore
};
var rsaProvider = new RSACryptoServiceProvider(cspParams);
var parameters = new RSAParameters()
{
Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
P = privateKey.P.ToByteArrayUnsigned(),
Q = privateKey.Q.ToByteArrayUnsigned(),
DP = privateKey.DP.ToByteArrayUnsigned(),
DQ = privateKey.DQ.ToByteArrayUnsigned(),
InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
D = privateKey.Exponent.ToByteArrayUnsigned(),
Exponent = privateKey.PublicExponent.ToByteArrayUnsigned()
};
rsaProvider.ImportParameters(parameters);
return rsaProvider;
}
并像这样添加它X509Store:
public static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
{
bool bRet = false;
try
{
X509Store store = new X509Store(st, sl);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
}
catch
{
}
return bRet;
}
基本上,我想将在Visual Studio中创建的证书上载到Azure门户或Microsoft注册门户中的应用程序清单,以便获得更强大的访问令牌,以用于将事件写入Outlook日历。我已经在Google上搜索了两天了,仍然没有运气...我是否缺少文档?
在Microsoft注册门户中创建新应用程序时,我需要在生成的appSecret上使用x509证书。
有人能指出我正确的方向吗?
答案 0 :(得分:1)
是否可以通过编程方式将在Visual Studios中创建的x509证书上传到Azure应用程序清单中?
是的,我们可以使用Microsoft.Azure.ActiveDirectory.GraphClient更新Azure应用程序mainfest。
我为此做了一个演示。以下是详细步骤,您可以参考:
如果要更新mainfest keyCredential,则需要 DELEGATED PERMISSIONS (删除权限)
1。注册一个天蓝色的AD 本地应用程序,并授予[以登录用户身份访问目录]权限。
2。创建一个控制台应用程序,在Program.cs文件中添加以下代码
private static async Task<string> GetAppTokenAsync(string graphResourceId, string tenantId, string clientId, string userId)
{
string aadInstance = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
IPlatformParameters parameters = new PlatformParameters(PromptBehavior.SelectAccount);
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance, false);
var authenticationResult = await authenticationContext.AcquireTokenAsync(graphResourceId, clientId, new Uri("http://localhost"), parameters, new UserIdentifier(userId, UserIdentifierType.UniqueId));
return authenticationResult.AccessToken;
}
var graphResourceId = "https://graph.windows.net";
var tenantId = "tenantId";
var clientId = "clientId";
var userId= "313e5ee2-b28exx-xxxx"; Then login user
var servicePointUri = new Uri(graphResourceId);
var serviceRoot = new Uri(servicePointUri, tenantId);
var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await GetAppTokenAsync(graphResourceId, tenantId, clientId, userName));
var cert = new X509Certificate();
cert.Import(@"D:\Tom\Documents\tom.cer");// the path fo cert file
var expirationDate = DateTime.Parse(cert.GetExpirationDateString()).ToUniversalTime();
var startDate = DateTime.Parse(cert.GetEffectiveDateString()).ToUniversalTime();
var binCert =cert.GetRawCertData();
var keyCredential = new KeyCredential
{
CustomKeyIdentifier = cert.GetCertHash(),
EndDate = expirationDate,
KeyId = Guid.NewGuid(),
StartDate = startDate,
Type = "AsymmetricX509Cert",
Usage = "Verify",
Value = binCert
};
var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;
application.KeyCredentials.Add(keyCredential);
application.UpdateAsync().Wait();
Packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Azure.ActiveDirectory.GraphClient" version="2.1.1" targetFramework="net471" />
<package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net471" />
<package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net471" />
<package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net471" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.8" targetFramework="net471" />
<package id="System.Spatial" version="5.6.4" targetFramework="net471" />
</packages>