{"id":18321767,"url":"https://github.com/yourtablecloth/pnpeople.security","last_synced_at":"2025-04-12T23:08:00.120Z","repository":{"id":110150043,"uuid":"466340853","full_name":"yourtablecloth/PnPeople.Security","owner":"yourtablecloth","description":"SEED Cryptography Algorithm Library for .NET Standard 2.0+","archived":false,"fork":false,"pushed_at":"2022-09-06T16:31:03.000Z","size":160,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-12-18T19:19:59.391Z","etag":null,"topics":["csharp","dotnet","hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yourtablecloth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["yourtablecloth"]}},"created_at":"2022-03-05T03:44:07.000Z","updated_at":"2023-08-01T02:01:32.000Z","dependencies_parsed_at":"2023-04-28T04:23:58.239Z","dependency_job_id":null,"html_url":"https://github.com/yourtablecloth/PnPeople.Security","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yourtablecloth%2FPnPeople.Security","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yourtablecloth%2FPnPeople.Security/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yourtablecloth%2FPnPeople.Security/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yourtablecloth%2FPnPeople.Security/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yourtablecloth","download_url":"https://codeload.github.com/yourtablecloth/PnPeople.Security/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230941554,"owners_count":18304010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","hacktoberfest"],"created_at":"2024-11-05T18:21:21.140Z","updated_at":"2024-12-23T09:33:04.550Z","avatar_url":"https://github.com/yourtablecloth.png","language":"C#","funding_links":["https://github.com/sponsors/yourtablecloth"],"categories":[],"sub_categories":[],"readme":"# PnPeople.Security\n\n[NuGet Package](https://www.nuget.org/packages/PnPeople.Security/)\n\nSEED Cryptography Algorithm Library for .NET Standard 2.0+\n\n## How to use\n\nYou can use this library to convert your SEED encrypted private key into a .NET standard RSA instance.\n\n1. First read the `.der` file and the `.key` file respectively into a byte array.\n1. Create an instance of the `System.Security.Cryptography.X509Certificates.X509Certificate2` class to read the public key data.\n1. Call the `GetPrivateKeyInfo` function of the `PnPeople.Security.CertPrivateKeyHelper` class to read the private key data.\n1. Prepare the certificate password by inputting it from the user.\n1. Call the `GetPrivateKeyDecryptor` function of the `PnPeople.Security.CertPrivateKeyHelper` class to obtain exact private key decryptor.\n1. When calling the decryptor delegate function, pass the private key information data and certificate password. The decryptor will return a standard RSA provider instance in .NET.\n\nNow you can use the RSA provider instance to sign the data.\n\n## Sample Code\n\nHere is the sample application code.\n\n```csharp\nvar folder = Path.Combine(\n    Environment.GetEnvironmentVariable(\"USERPROFILE\"),\n    \"AppData\", \"LocalLow\", \"NPKI\");\n\nforeach (var eachProviderDirectory in Directory.GetDirectories(folder))\n{\n    Console.WriteLine($\"[{Path.GetFileName(eachProviderDirectory)}]\");\n\n    foreach (var eachDirectory in Directory.GetDirectories(Path.Combine(eachProviderDirectory, \"USER\")))\n    {\n        Console.WriteLine($\"{Path.GetFileName(eachDirectory)}\");\n        var certFile = Directory.GetFiles(eachDirectory, \"*.der\", SearchOption.TopDirectoryOnly).FirstOrDefault();\n\n        X509Certificate2 token = null;\n\n        if (certFile != null \u0026\u0026 File.Exists(certFile))\n        {\n            token = new X509Certificate2(X509Certificate.CreateFromCertFile(certFile));\n\n            Console.WriteLine(\"- IssuerName: \" + token.Issuer);\n            Console.WriteLine(\"- KeyAlgorithm: \" + token.GetKeyAlgorithm());\n            Console.WriteLine(\"- KeyAlgorithmParameters: \" + token.GetKeyAlgorithmParametersString());\n            Console.WriteLine(\"- Name: \" + token.Subject);\n            Console.WriteLine(\"- PublicKey: \" + token.GetPublicKeyString());\n            Console.WriteLine(\"- SerialNumber: \" + token.GetSerialNumberString());\n            Console.WriteLine(\"- HasPrivateKey: \" + token.HasPrivateKey);\n\n            var currentDateTime = DateTime.Now;\n            if (currentDateTime \u003c= token.NotBefore)\n            {\n                Console.WriteLine(\"- Certificate is not valid yet.\");\n                continue;\n            }\n            else if (token.NotAfter \u003c= currentDateTime)\n            {\n                Console.WriteLine(\"- Certificate has expiered.\");\n                continue;\n            }\n        }\n\n        var keyFile = Directory.GetFiles(eachDirectory, \"*.key\", SearchOption.TopDirectoryOnly).FirstOrDefault();\n\n        if (keyFile == null || !File.Exists(keyFile))\n            continue;\n\n        var bytes = File.ReadAllBytes(keyFile);\n        var privKeyInfo = CertPrivateKeyHelper.GetPrivateKeyInfo(bytes);\n        Console.WriteLine(\"- KeyType: \" + privKeyInfo.KeyType);\n        Console.WriteLine(\"- Algorithm: \" + privKeyInfo.Algorithm);\n\n        Console.Write(\"- Type private key password: \");\n        var passwd = ReadPasswordFromConsole();\n\n        var copiedPassword = CertPrivateKeyHelper.CopyFromSecureString(passwd);\n        var decryptor = CertPrivateKeyHelper.GetPrivateKeyDecryptor(privKeyInfo);\n\n        if (decryptor == null)\n        {\n            Console.WriteLine(\"- Unsupported algorithm found.\");\n            continue;\n        }\n\n        var provider = decryptor.Invoke(privKeyInfo, copiedPassword);\n\n        if (provider != null)\n        {\n            var randomString = string.Concat(Enumerable.Range(1, (int)(Math.Abs(DateTime.Now.Ticks) % 9)).Select(x =\u003e Guid.NewGuid().ToString(\"n\")));\n            var buffer = Encoding.Default.GetBytes(randomString);\n            var signed = provider.SignData(buffer, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);\n            var result = provider.VerifyData(buffer, signed, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);\n\n            Console.WriteLine($\"- Signature Validation Result: {(result ? \"Valid\" : \"Invalid\")}\");\n\n            if (result \u0026\u0026 token != null)\n            {\n                var tokenWithPrivateKey = token.CopyWithPrivateKey(provider);\n                var directoryPath = Path.GetDirectoryName(certFile);\n\n                var pfxData = tokenWithPrivateKey.Export(X509ContentType.Pfx, passwd);\n                var pfxPath = Path.Combine(directoryPath, \"signCertNew.pfx\");\n                File.WriteAllBytes(pfxPath, pfxData);\n\n                if (File.Exists(pfxPath))\n                    Console.WriteLine($\"- PFX Converted: {pfxPath}\");\n\n                // Separate PFX back into DER/KEY (but don't use SEED encryption)\n                tokenWithPrivateKey = new X509Certificate2(File.ReadAllBytes(pfxPath), passwd, X509KeyStorageFlags.Exportable);\n\n                var certData = tokenWithPrivateKey.Export(X509ContentType.Cert);\n                var certPath = Path.Combine(directoryPath, \"signCertNew.der\");\n                File.WriteAllBytes(certPath, certData);\n\n                if (File.Exists(certPath))\n                    Console.WriteLine($\"- Certificate converted: {certPath}\");\n\n                // https://www.rootca.or.kr/kcac/down/Guide/Implementation_Guideline_for_Safe_Usage_of_Accredited_Certificate_using_bio_information_in_Smart_phone.pdf\n                // According to the contents of '2.2 Authenticated Certificate Digital Signature Creation Information Storage Plan' of the above document, IterationCount seems to be promised to 2048.\n                var keyData = tokenWithPrivateKey.PrivateKey.ExportEncryptedPkcs8PrivateKey(\n                    copiedPassword,\n                    new PbeParameters(PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 2048));\n\n                var keyPath = Path.Combine(directoryPath, \"signPriNew.key\");\n                File.WriteAllBytes(keyPath, keyData);\n\n                if (File.Exists(keyPath))\n                    Console.WriteLine($\"- Private key converted: {keyPath}\");\n            }\n        }\n        else\n        {\n            Console.WriteLine($\"- Cannot decrypt private key\");\n        }\n    }\n}\n```\n\n## License\n\nThis project is licensed under the MIT License.\n\nOriginal Source Code Excerpted From:\n\n- [https://thermidor.tistory.com/430](https://thermidor.tistory.com/430)\n- [https://thermidor.tistory.com/431](https://thermidor.tistory.com/431)\n- [Mono.Security](https://github.com/mono/mono/tree/5d2e3bc3b3c8184d35b2f7801e88d96470d367c4/mcs/class/Mono.Security)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyourtablecloth%2Fpnpeople.security","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyourtablecloth%2Fpnpeople.security","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyourtablecloth%2Fpnpeople.security/lists"}