Tuesday, March 14, 2023

Create PFX file from Root files Key/PFX

If you have Root.key and Root.pfx file and you would like to create new PFX file, below is the solution.

I have used. 

  1. .NET Core 6.0 with Visual Studio 2022 Ver 17.4.3
  2. "Portable.BouncyCastle" Version 1.9.0 from Nuget 
  3. "Microsoft.Extensions.Configuration" Version 7.0.0 from Nuget

Here the working solution, use in your class and use it 

using Org.BouncyCastle.Asn1;

using Org.BouncyCastle.Asn1.Pkcs;

using Org.BouncyCastle.Asn1.X509;

using Org.BouncyCastle.Crypto;

using Org.BouncyCastle.Crypto.Generators;

using Org.BouncyCastle.Crypto.Parameters;

using Org.BouncyCastle.Crypto.Prng;

using Org.BouncyCastle.Math;

using Org.BouncyCastle.Pkcs;

using Org.BouncyCastle.Security;

using Org.BouncyCastle.Utilities;

using Org.BouncyCastle.X509;

using System.Security.Cryptography.X509Certificates;

 public void CreateSelfSignedPFXFile()

 {

    string RootKeyFilePath = @"C:\Test\RootFile.key";

    string RootPfxFilePath = @"C:\Test\RootFile.pfx";

    string pass = "Pass123#";

     //Need file name to have all certificate export into this file

     string newPFXFileName = @"C:\Test\NewCertificate.pfx";

     System.Security.Cryptography.X509Certificates.X509Certificate2 certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(RootPfxFilePath,pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet |X509KeyStorageFlags.Exportable);

    string subject = "E=test@test.com, CN=Test Name, OU=ORG, O=LSGS, L=Orlando, ST=MN,C=US";

    try

    {

     using var reader = File.OpenText(RootKeyFilePath);

     AsymmetricKeyParameter? myCAprivateKey = ((AsymmetricCipherKeyPair)new                 Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject())?.Private;

     //Create the cert based on the CA cert privateKey and have new subject

     X509Certificate2 MyCert = GenerateSelfSignedCertificate(subject,                         certificate.Issuer.Replace("S=","ST="), myCAprivateKey, pass);

     //Export as pfx with privatekey

     byte[] certData = MyCert.Export(X509ContentType.Pfx, pass);

    File.WriteAllBytes(newPFXFileName, certData);

    }

    catch (Exception exc){Console.WriteLine(exc.Message);}

     }

     public X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter? issuerPrivKey, string pass)

     {

     const int keyStrength = 2048;

     // Generating 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);

    // Signature Algorithm

    const string signatureAlgorithm = "SHA256WithRSA";

    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name

    X509Name subjectDN = new X509Name(subjectName);

    X509Name issuerDN = new X509Name(issuerName);

    certificateGenerator.SetIssuerDN(issuerDN);

    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For

    DateTime notBefore = DateTime.UtcNow.Date;

    DateTime notAfter = notBefore.AddYears(10);

    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);

    // Generating the Certificate

    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

    // selfsign certificate

    Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerPrivKey, random);

    // correcponding private key

    PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

// merge into X509Certificate2

    X509Certificate2 x509 = new         System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded(),    pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet |     X509KeyStorageFlags.Exportable);

     //below does not work for Window

     //Asn1Sequence seq =(Asn1Sequence)Asn1Object.FromStream(info.PrivateKeyData.GetDerEncoded());

     //use this one

     Asn1Sequence seq =(Asn1Sequence)Asn1Object.FromStream(info.PrivateKeyData.GetOctetStream());

     if (seq.Count != 9)

     {

     //throw new PemException("malformed sequence in RSA private key");

     }

     //Create the Private Key

     RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);

     RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(

     rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

     //below does not work for Window

     //x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);

    //use this one 

    var rsa1 = DotNetUtilities.ToRSA(rsaparams);

     var cert = x509.CopyWithPrivateKey(rsa1);

    return cert;

}

Troubleshoots-1

subject should have all correct object , if you pass wrong object then will get error 

Error: "Unknown object id - S - passed to distinguished name"

like: string subject = "E=test@test.com, CN=Test Name, OU=ORG, O=LSGS, L=Orlando, S=MN,C=US";

Ref: for all correct object to be used see here Distinguished Names | Microsoft Learn

Troubleshoots-2

If you are typing wrong password for key certificate, you will get following error 

Error: Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The specified network password is not correct.'

Make sure you know the correct password.

Troubleshoots-3

If you forgot to create private key at the end then you will get following error 
Error: No Private key
you must need to add private key by using "var cert = x509.CopyWithPrivateKey(rsa1);"

Friday, May 08, 2020

Error message 401.2.: Unauthorized: Logon failed due to server configuration. IIS Express ASP.NET

When you are running ASP.net application using visual studio and configured to run with IIS Express and if you are getting following error, I resolved to following below steps.

Error message 401.2.: Unauthorized: Logon failed due to server configuration.



Friday, November 22, 2019

Error: Parser Error Message: Could not load type” in Global.asax

I resolved this error to change project OutputPath property to "bin" instead of "bin\Debug" or "bin\Release"

Go to the Project right click and select Property > Compile and change "Build output path" to "bin\"


or Unload project and open for Edit and Modify Outputpath property to "bin\" instead of "bin\Debug" or "bin\Release".
and also you can check IIS pool should be in correct .NET version (2.0 or 4.0)

Create Pipeline build to Push DLL into Nuget Repository using Azure DevOps


Here simple steps to follow and create new Automated Build using Azure DevOps to push your DLLs into NuGet Repository 

You mainly needed three task to Restore, Pack and Push library into NuGet repository.

Go to Pipeline > Build > Create New Build , Add following Task on your build 

  1. Get a Sources
    1. Choose Repository (TFVC or Git)
  2. Add Agent Job
    1. NuGet Tool Installer : leave all default
                                                    i.     Type: Map
                                                   ii.     Server Path: choose source code location
                                                  iii.     Clean: true
                                                  iv.     Clean Options: sources
                                                   v.     Label sources: OnSuccess
                                                  vi.     Label format: $(Build.BuildNumber)
    1. NuGet  for Restore
                                                    i.     Choose command : restore
                                                   ii.     Path to solution, packages.config, or project.json (.sln file path)
                               iii.     Use packages from this Azure Artifacts/TFS feed
                                iv.     Check: Use packages from NuGet.org
    1. Update AssemblyInfo
                                                    i.     Root Folder: $(Build.SourcesDirectory)
                                                   ii.     File pattern (AssemblyInfo.cs)
                                                  iii.     Version: $(Build.BuildNumber)
                                                  iv.     File Version: $(Build.BuildNumber)
    1. Visual Studio Build
                                                    i.     Solution :   .sln file path
                                                   ii.     Visual Studio Version: Latest
                                                  iii.     Platform : AnyCPU
                                                  iv.     Configuration: Release
                                                   v.     Check: Clean
    1. NuGet (for pack)
                                                    i.     Command: pack
                                                   ii.     Path for proj or nuspec
                                                  iii.     Pack Option: “Use the build number”
    1. NuGet (for Push)
                                                    i.     Command : push
                                                   ii.     Path to NuGet package to publish ($(Build.ArtifactStagingDirectory)/*.nupkg)
                                                  iii.     Target Feed: Select a feed hosted in this account. You must have Package Management installed and licensed to select a feed here.”

Go to this video for more details 

Common errors when you automate build using Azure DevOps build


Error-1
The nuget command failed with exit code(1) and error(System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: Cannot determine the packages folder to restore NuGet packages. Please specify either -PackagesDirectory or -SolutionDirectory.

Solution
I observed this error when I was trying to create automated build using Azure DevOps Pipeline and I changed **/*.csproj  from **/*.Sln as a file to build.

To Resolve this error, in the Pipeline Task select  NuGet & use Pack Option instead of Restore Option, Restore Option work for Solution file only not for project file.

Error-2
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(775,5): Error : The OutputPath property is not set for project 'ABC.csproj'.  Please check to make sure that you have specified a valid combination of Configuration and Platform for this project.  Configuration='Release'  Platform='Any CPU'.  You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project.

Solution
Again if you are switching from .Sln file to .csproj or .vbproj file to be build then make sure you are selecting the correct "Platform" property.

For Project file , Platform property value is "AnyCPU" and 
For Solution file, Platform property value is "Any CPU" (with space)

so, you need to open project file in notepad and check PropertyGroup section and OutputPath tag should look like below.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <OutputPath>bin\Release\</OutputPath>
      .
      .
</PropertyGroup>

Error-3
Response status code does not indicate success: 409 (Conflict - The feed already contains “*.dll <Version Number>”)

Solution:
When you get this error that mean project is building correctly but not increasing the build number, so server trying to push same dll version into NuGet and it not allow duplicate version number, and throw 409 error
If you choose "Skip duplicate version" option then it will resolve the issues but that will not be correct because latest version never deployed into NuGet server. 

The best solution I found, in NuGet Task select following option 
Command : pack
Automatic package versioning : Use the build numbers 

This will create new version every time when new DLL build successfully, so No 409 error.

Wednesday, November 13, 2019

Error: The visual tree has been changed during a 'VisualTreeChanged' event.

Error: The visual tree has been changed during a 'VisualTreeChanged' event.

Solution: 
Go to Visual Studio, Tools >> Options and unchecked "Enable UI Debugging Tools for XMAL"

 

Tuesday, November 12, 2019

Error: The authentication schemes configured on the host ('Ntlm, Anonymous') do not allow those configured on the binding 'BasicHttpBinding' ('Negotiate'). Please ....

ErrorThe authentication schemes configured on the host ('Ntlm, Anonymous') do not allow those configured on the binding 'BasicHttpBinding' ('Negotiate').  Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly.  Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.

Solution:

I have done following two things in IIS setting to resolve following error

1) Make sure for Hosted WebSite/App two Authentication option is set to Enabled
     Anonymous Authentication = Enabled and Window Authentication = Enabled


2) Right click on Window Authentication >> Providers
     make sure you have NTLM and Negotiate is added as Enabled Providers, If not just add it.



Sunday, May 19, 2019

How to add innerHTML or Multi line text to NgbPopover


I was trying to show multi line text on Popover and want to format my display contain as I want using HTML tag. text construction has to be done in .ts file.

I achieved this in following way.

Label where, on mouseover I want to show popover with employee detail data.
I want when use mouseover then popover display and if user click outside or click “esc” then popover disappears. You can also use moverover and mouse leave using triggers="mouseenter:mouseleave"

npm install --save @ng-bootstrap/ng-bootstrap

app.module.ts

//Popover- menu item
import { NgbPopoverModule, NgbModalModule, NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
@NgModule({imports: [NgbPopoverModule]})

Employee.html file 

            name="EmployeeProfile "
(mouseover)="getEmployeeProfileData()"
            [ngbPopover]="ShowEmployeeProfile" 
popoverTitle="Employee Detail Profile"
            triggers="mouseenter" [autoClose]="'outside'">
</label>

 <ng-template #ShowEmployeeProfile >
 <div[innerHtml]="employeeDetailDataForToolTip"</div>
</ng-template>

Employee.ts file

employeeDetailDataForToolTip: string ="";

getEmployeeProfileData(): string
{
this.employeeDetailDataForToolTip="";
this.employeeDetailDataForToolTip+='<ul><u>Ritesh Kesharwani</u>';
this.employeeDetailDataForToolTip+='<li>Address: Mile City, USA</lt;li>';
this.employeeDetailDataForToolTip+='<li> Department: Education</li>';
this.employeeDetailDataForToolTip+='<li> Salary: $300000</li>';
this.employeeDetailDataForToolTip+='<li> Base Location: MN</li></ul>'
}
If you want scroll bar on Popover then you need to override style sheet
.popover {
  max-width500px !important;
  background#F9F9F9 !important;
  max-height400px !important;
  overflowscroll !important;
}

sample pop over on label mouse over