C#的RSA加密解密签名,就为了支持PEM PKCS#8格式密钥对的导入导出

差点造了一整个轮子

.Net Framework 4.5 里面的RSA功能,并未提供简单对PEM密钥格式的支持(.Net Core有咩?),差点(还远着)造了一整个轮子,就为了支持PEM PKCS#8、PKCS#1格式密钥对的导入导出。

Github: https://github.com/xiangyuecn/RSA-csharp

本文内容来自README,主要介绍了PEM PKCS#8、PKCS#1公钥和私钥格式,并以此为基础写的C#函数方法。

前言、自述、还有啥

在写一个小转换工具时加入了RSA加密解密支持(见图RSA工具),秘钥输入框支持填写XML和PEM格式,操作类型里面支持XML->PEM、PEM->XML的转换。

实现相应功能发现原有RSA操作类不能良好工作,PEM->XML没问题,只要能通过PEM创建RSA,就能用RSACryptoServiceProvider自带方法导出XML。但XML->PEM没有找到相应的简单实现方法,大部分博客写的用BouncyCastle库来操作,代码是少,但BouncyCastle就有好几兆大小,我的小工具啊才100K;所以自己实现了一个支持导出PKCS#1PKCS#8格式PEM密钥的方法RSA_PEM.ToPEM

操作过程中发现原有RSA操作类不支持用PKCS#8格式PEM密钥来创建RSA对象(用的RSACryptoServiceProviderExtension的扩展方法来支持PEM密钥),仅支持PKCS#1,所以又自己实现了一个从PEM密钥来创建RSACryptoServiceProvider的方法RSA_PEM.FromPEM

在实现导入导出PEM密钥过程中,对PKCS#1PKCS#8格式的PEM密钥有了一定的了解,主要参考了:

《RSA公钥文件(PEM)解析》:公钥字节码分解。

《RSA私钥文件(PEM)解析》:私钥字节码分解。

《iOS安全相关 - RSA中公钥的DER格式组成》:1字节和2字节长度表述方法,和为什么有些字段前面要加0x00。

跑起来

clone下来用vs应该能够直接打开,经目测看起来没什么卵用的文件都svn:ignore掉了(svn滑稽。

主要支持

  • 通过XML格式密钥对创建RSA

  • 通过PEM格式密钥对创建RSA

  • RSA加密、解密

  • RSA签名、验证

  • 导出XML格式公钥、私钥

  • 导出PEM格式公钥、私钥

  • PEM格式秘钥对和XML格式秘钥对互转

PEM密钥编码格式

长度表述方法

PEM格式中,每段数据基本上都是flag+长度数据占用位数+长度数值+数据这种格式。

长度数据占用位数有0x81和0x82两个值,分别代表长度数值占用了1字节和2字节。

但长度数据占用位数不一定存在,如果长度数值<0x80时(理由应该和下面这个加0x00一致),长度数值直接在flag后面用1位来表述,变成了flag+长度数值(<0x80)+数据

什么情况下内容前面要加0x00

如果内容的bit流的前4 bit十六进制值>=8就要在内容前面加0x00,其他不用加。

一个大整数,最高位为符号位,其为1时,就是负数,所以要在最高位填充0x00以保证不为负。

PEM公钥编码格式

PKCS#1PKCS#8公钥编码都是统一的格式。

/*****1024字节公钥*****/-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYw9+M3+REzDtYqwBrs/as/Oy8
GRE5OmnqOV0EfkEiCIjiczbVEFnZ3qRjLbDATfmBxNQ6c6Fga8nX28glEH/aL/RG2KdpI8KMUqKAszNydsHSeh9MSKcd5zgS4NuE0u+eR7CB8kOWipiLDQmY38kpM36p
RWdNQlpIaTDo5IhJJwIDAQAB
-----END PUBLIC KEY-----/*****二进制表述*****/30819F300D06092A864886F70D010101050003818D003081890281810098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E48849270203010001/*****二进制分解*****//*
后续(到结尾)内容长度为0x9F字节,相当于整个文件长度-当前这4字节。
格式:tag[+长度数据占用位数(可选)]+后续长度数值,此处tag=0x30,长度数据占用1位(参考前面长度表述方法),后续长度数值=0x9F个字节
*/30 81 9F/*
固定内容 encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"(其实不懂是啥玩意)
*/30 0D 06092A864886F70D0101010500/*后续内容长度,后面内容长度为0x8D字节,和开头格式一致*/03 81 8D/*固定内容*/00/*后续内容长度,后面内容长度为0x89字节,和开头格式一致*/30 81 89/*
RSA Modulus内容
格式:tag[+长度数据占用位数(可选)]+内容长度数值+内容,此处tag=0x02,所有RSA相关参数都是用02,长度数据占用位数为1字节,内容长度数值=0x81个字节,内容为0x00-0x27这一段(参考前面什么情况下要加0x00)。
*/02 81 810098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E4884927/*RSA Exponent内容,和Modulus一样,但此处长度数据占用位数不存在*/02 03 010001

PEM PKCS#1私钥编码格式

/*****1024字节PKCS#1私钥*****/-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCYw9+M3+REzDtYqwBrs/as/Oy8GRE5OmnqOV0EfkEiCIjiczbV
EFnZ3qRjLbDATfmBxNQ6c6Fga8nX28glEH/aL/RG2KdpI8KMUqKAszNydsHSeh9M
SKcd5zgS4NuE0u+eR7CB8kOWipiLDQmY38kpM36pRWdNQlpIaTDo5IhJJwIDAQAB
AoGAcGNSWRrynia+1onf4lzg8v2U0QGEKV0vRNF0/HRCSN6MjkUDJxdDc0UYHZsk
uSXklTMQi/w70msacQNRqOsNk32O6vVPxr4NfTVaIV59Jv9Z5SXGiRmRZXeRw0ks
KYdOwaDJJu9zETNHZoMFJm8sq/tGJPQCPNesoZRZssL7mjkCQQDOI6jKt60bvu6V
XvtQoyUUbyMj9eCOBatS49jRvv326TMc951e9TcbnD0cxJrV1N6yIi+++ejwfagb
eYf++N61AkEAvbc8KTlBbI9TMwnVkQpst+ckgm3gpRDhAfQ/Lt7r8g2KAHsJv+wb
AJCgu8PgqM9mQjVxZ+78+aLEQ+h5rvMV6wJAY1c9/ct8ihV+Zs+qL1cgBHP2rFrO
x8KlqMGS+KmhPD9v2XLfDScBUrX9oYKB17DJTXE6Lz/CaTs1K2BrEI4gzQJBAJIQ
s9chaAfHSc1v8uha2F23Ltrk8iLknfi9LrBNneedGPVJxbXoeNm0gKxQIXaXSCoN
r6TP0iH5eZa3NIjIS8UCQAbw+d2WJIon+vuUsKk2dtZTqZx8e53NreZUFMaIkoS5
JPJqI6/6hq8/2ARFO3P9/qkxDMkJv8mSjV91cZixB10=
-----END RSA PRIVATE KEY-----/*****二进制表述*****/3082025C0201000281810098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E48849270203010001028180706352591AF29E26BED689DFE25CE0F2FD94D10184295D2F44D174FC744248DE8C8E45032717437345181D9B24B925E49533108BFC3BD26B1A710351A8EB0D937D8EEAF54FC6BE0D7D355A215E7D26FF59E525C6891991657791C3492C29874EC1A0C926EF73113347668305266F2CABFB4624F4023CD7ACA19459B2C2FB9A39024100CE23A8CAB7AD1BBEEE955EFB50A325146F2323F5E08E05AB52E3D8D1BEFDF6E9331CF79D5EF5371B9C3D1CC49AD5D4DEB2222FBEF9E8F07DA81B7987FEF8DEB5024100BDB73C2939416C8F533309D5910A6CB7E724826DE0A510E101F43F2EDEEBF20D8A007B09BFEC1B0090A0BBC3E0A8CF6642357167EEFCF9A2C443E879AEF315EB024063573DFDCB7C8A157E66CFAA2F57200473F6AC5ACEC7C2A5A8C192F8A9A13C3F6FD972DF0D270152B5FDA18281D7B0C94D713A2F3FC2693B352B606B108E20CD0241009210B3D7216807C749CD6FF2E85AD85DB72EDAE4F222E49DF8BD2EB04D9DE79D18F549C5B5E878D9B480AC50217697482A0DAFA4CFD221F97996B73488C84BC5024006F0F9DD96248A27FAFB94B0A93676D653A99C7C7B9DCDADE65414C6889284B924F26A23AFFA86AF3FD804453B73FDFEA9310CC909BFC9928D5F757198B1075D/*****二进制分解(大部分和公钥格式相同)*****//*后续内容长度,后面内容长度为0x025C个字节,和公钥开头格式一致,参考公钥部分*/30 82 025C/*固定版本号*/02 01 00/*#####从这里开始后面就是内容了 注:KCS#8仅仅是在此处插入部分内容#####*//*RSA Modulus内容,和公钥开头格式一致,参考公钥部分*/02 81 81 0098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E4884927/*RSA Exponent*/02 03 010001/*RSA D*/02 81 80706352591AF29E26BED689DFE25CE0F2FD94D10184295D2F44D174FC744248DE8C8E45032717437345181D9B24B925E49533108BFC3BD26B1A710351A8EB0D937D8EEAF54FC6BE0D7D355A215E7D26FF59E525C6891991657791C3492C29874EC1A0C926EF73113347668305266F2CABFB4624F4023CD7ACA19459B2C2FB9A39/*RSA P*/02 4100CE23A8CAB7AD1BBEEE955EFB50A325146F2323F5E08E05AB52E3D8D1BEFDF6E9331CF79D5EF5371B9C3D1CC49AD5D4DEB2222FBEF9E8F07DA81B7987FEF8DEB5/*RSA Q*/02 4100BDB73C2939416C8F533309D5910A6CB7E724826DE0A510E101F43F2EDEEBF20D8A007B09BFEC1B0090A0BBC3E0A8CF6642357167EEFCF9A2C443E879AEF315EB/*RSA DP*/02 40 63573DFDCB7C8A157E66CFAA2F57200473F6AC5ACEC7C2A5A8C192F8A9A13C3F6FD972DF0D270152B5FDA18281D7B0C94D713A2F3FC2693B352B606B108E20CD/*RSA DQ*/02 41009210B3D7216807C749CD6FF2E85AD85DB72EDAE4F222E49DF8BD2EB04D9DE79D18F549C5B5E878D9B480AC50217697482A0DAFA4CFD221F97996B73488C84BC5/*RSA InverseQ*/02 4006F0F9DD96248A27FAFB94B0A93676D653A99C7C7B9DCDADE65414C6889284B924F26A23AFFA86AF3FD804453B73FDFEA9310CC909BFC9928D5F757198B1075D

PEM PKCS#8私钥编码格式

/*****1024字节PKCS#8私钥*****/-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJjD34zf5ETMO1ir
AGuz9qz87LwZETk6aeo5XQR+QSIIiOJzNtUQWdnepGMtsMBN+YHE1DpzoWBrydfb
yCUQf9ov9EbYp2kjwoxSooCzM3J2wdJ6H0xIpx3nOBLg24TS755HsIHyQ5aKmIsN
CZjfySkzfqlFZ01CWkhpMOjkiEknAgMBAAECgYBwY1JZGvKeJr7Wid/iXODy/ZTR
AYQpXS9E0XT8dEJI3oyORQMnF0NzRRgdmyS5JeSVMxCL/DvSaxpxA1Go6w2TfY7q9U/Gvg19NVohXn0m/1nlJcaJGZFld5HDSSwph07BoMkm73MRM0dmgwUmbyyr+0Yk9AI816yhlFmywvuaOQJBAM4jqMq3rRu+7pVe+1CjJRRvIyP14I4Fq1Lj2NG+/fbp
Mxz3nV71NxucPRzEmtXU3rIiL7756PB9qBt5h/743rUCQQC9tzwpOUFsj1MzCdWR
Cmy35ySCbeClEOEB9D8u3uvyDYoAewm/7BsAkKC7w+Coz2ZCNXFn7vz5osRD6Hmu8xXrAkBjVz39y3yKFX5mz6ovVyAEc/asWs7HwqWowZL4qaE8P2/Zct8NJwFStf2h
goHXsMlNcTovP8JpOzUrYGsQjiDNAkEAkhCz1yFoB8dJzW/y6FrYXbcu2uTyIuSd
+L0usE2d550Y9UnFteh42bSArFAhdpdIKg2vpM/SIfl5lrc0iMhLxQJABvD53ZYk
iif6+5SwqTZ21lOpnHx7nc2t5lQUxoiShLkk8mojr/qGrz/YBEU7c/3+qTEMyQm/
yZKNX3VxmLEHXQ==
-----END PRIVATE KEY-----/*****二进制表述*****/30820276020100300D06092A864886F70D0101010500048202603082025C0201000281810098C3DF8CDFE444CC3B58AB006BB3F6ACFCECBC1911393A69EA395D047E41220888E27336D51059D9DEA4632DB0C04DF981C4D43A73A1606BC9D7DBC825107FDA2FF446D8A76923C28C52A280B3337276C1D27A1F4C48A71DE73812E0DB84D2EF9E47B081F243968A988B0D0998DFC929337EA945674D425A486930E8E48849270203010001028180706352591AF29E26BED689DFE25CE0F2FD94D10184295D2F44D174FC744248DE8C8E45032717437345181D9B24B925E49533108BFC3BD26B1A710351A8EB0D937D8EEAF54FC6BE0D7D355A215E7D26FF59E525C6891991657791C3492C29874EC1A0C926EF73113347668305266F2CABFB4624F4023CD7ACA19459B2C2FB9A39024100CE23A8CAB7AD1BBEEE955EFB50A325146F2323F5E08E05AB52E3D8D1BEFDF6E9331CF79D5EF5371B9C3D1CC49AD5D4DEB2222FBEF9E8F07DA81B7987FEF8DEB5024100BDB73C2939416C8F533309D5910A6CB7E724826DE0A510E101F43F2EDEEBF20D8A007B09BFEC1B0090A0BBC3E0A8CF6642357167EEFCF9A2C443E879AEF315EB024063573DFDCB7C8A157E66CFAA2F57200473F6AC5ACEC7C2A5A8C192F8A9A13C3F6FD972DF0D270152B5FDA18281D7B0C94D713A2F3FC2693B352B606B108E20CD0241009210B3D7216807C749CD6FF2E85AD85DB72EDAE4F222E49DF8BD2EB04D9DE79D18F549C5B5E878D9B480AC50217697482A0DAFA4CFD221F97996B73488C84BC5024006F0F9DD96248A27FAFB94B0A93676D653A99C7C7B9DCDADE65414C6889284B924F26A23AFFA86AF3FD804453B73FDFEA9310CC909BFC9928D5F757198B1075D/*****二进制分解(和PKCS#1只是多了一段数据,详细结构参考PKCS#1的)*****//*后续内容长度*/30 82 0276/*固定版本号*/02 01 00/*#####相对于KCS#1仅仅是在此处开始插入部分数据 Begin#####*//*
固定内容 encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"(其实不懂是啥玩意)
*/30 0D 06092A864886F70D0101010500/*后续内容长度,后面内容长度为0x0260字节,和开头格式一致*/04 82 0260/*后续内容长度,后面内容长度为0x025C字节,和开头格式一致*/30 82 025C/*固定版本号*/02 01 00/*#####相对于KCS#1仅仅是在此处结束插入部分数据 End#####*//*RSA Modulus内容*/02 81 81 0098C3DF8CDFE444CC3B58A......后续内容省略...

C# RSA操作类

主要文件

RSA.cs

此文件依赖RSA_PEM.cs,用于进行加密、解密、签名、验证、秘钥导入导出操作。

[构造函数] new RSA(1024)

通过指定密钥长度来创建RSA,会生成新密钥。

[构造函数] new RSA("<xml>")

通过XML格式密钥对创建RSA,xml可以是公钥或私钥,XML格式如:

<RSAKeyValue><Modulus>mMPfjN/kRMw7WKsAa7P2rPzsvBkROTpp6jldBH5BIgiI4nM21RBZ2d6kYy2wwE35gcTUOnOhYGvJ19vIJRB/2i/0RtinaSPCjFKigLMzcnbB0nofTEinHec4EuDbhNLvnkewgfJDloqYiw0JmN/JKTN+qUVnTUJaSGkw6OSISSc=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

[构造函数] new RSA("PEM"any)

通过PEM格式密钥对创建RSA,PEM可以是公钥或私钥,支持PKCS#1PKCS#8格式,PEM格式如:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYw9+M3+REzDtYqwBrs/as/Oy8
GRE5OmnqOV0EfkEiCIjiczbVEFnZ3qRjLbDATfmBxNQ6c6Fga8nX28glEH/aL/RG2KdpI8KMUqKAszNydsHSeh9MSKcd5zgS4NuE0u+eR7CB8kOWipiLDQmY38kpM36p
RWdNQlpIaTDo5IhJJwIDAQAB
-----END PUBLIC KEY-----

[方法] .ToXML([false]是否仅仅导出公钥)

导出XML格式秘钥对。如果RSA包含私钥,默认会导出私钥,设置仅仅导出公钥时只会导出公钥;不包含私钥只会导出公钥。

[方法] .ToPEM_PKCS1|.ToPEM_PKCS8([false]是否仅仅导出公钥)

导出PEM格式秘钥对,两个方法分别导出PKCS#1PKCS#8格式。如果RSA包含私钥,默认会导出私钥,设置仅仅导出公钥时只会导出公钥;不包含私钥只会导出公钥。

[方法] .Encode("字符串"|bytes)

加密操作,支持任意长度数据。

[方法] .DecodeOrNull("Base64字符串"|bytes)

解密操作,解密失败返回null,支持任意长度数据。

[方法] .Sign("hash""字符串"|bytes)

通过hash算法(MD5、SHA1等)来对数据进行签名。

[方法] .Verify("hash""sign""字符串")

通过hash算法(MD5、SHA1等)来验证字符串是否和sign签名一致。

RSA_PEM.cs

此文件不依赖任何文件,可以单独copy来用(RSA_Unit里面的方法可以忽略)

[静态方法] .FromPEM("PEM")

通过PEM格式秘钥对来创建RSACryptoServiceProvider,PEM可以是公钥或私钥。

[静态方法] .ToPEM(RSACryptoServiceProviderexportPublicOnlyusePKCS8)

将RSA中的密钥对导出成PEM格式usePKCS8=false时返回PKCS#1格式,否则返回PKCS#8格式。如果RSA包含私钥,默认会导出私钥,设置仅仅导出公钥时只会导出公钥;不包含私钥只会导出公钥。

次要文件

RSA_Unit.cs

封装的一些通用方法,如:base64。没有此文件也可以,引用的地方用别的代码实现。

Program.cs

控制台入口文件,用来测试的,里面包含了主要的使用用例。

图例

RSA工具:

640?wx_fmt=png

控制台运行:

640?wx_fmt=png

原文地址: https://www.cnblogs.com/xiangyuecn/p/9922325.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

福州首届.NET开源社区技术交流会圆满成功

活动总结2018年11月10日周六的下午&#xff0c;在福州蒲公英创新工场举办了福州首届.NET开源社区技术交流会&#xff0c;来自福建省各大科技公司的技术小伙伴齐聚一堂&#xff0c;为了就是能在现场学习到微软跨平台技术.NET Core、微服务以及Azure云服务。在交流会现场&#xf…

.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐

引子为什么写这篇文章呢&#xff1f;因为.NET Core的生态越来越好了&#xff01;之前玩转.net的时候操作Redis相信大伙都使用过一些组件&#xff0c;但都有一些缺点&#xff0c;如ServiceStack.Redis 是商业版&#xff0c;免费版有限制&#xff1b;StackExchange.Redis 是免费版…

P2495 [SDOI2011]消耗战(树形dp+虚树)

P2495 [SDOI2011]消耗战 树形dp 状态表示&#xff1a;fuf_ufu​表示以uuu为根的子树中&#xff0c;uuu节点与子树中的关键的“隔开”所需要的最小代价 状态转移&#xff1a; 考虑uuu的一个儿子vvv vvv是关键点&#xff1a;fufuwu→vf_uf_uw_{u\to v}fu​fu​wu→v​vvv不是关键…

【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置(2)

上篇文章我们介绍了如何扩展Ocelot网关&#xff0c;并实现数据库存储&#xff0c;然后测试了网关的路由功能&#xff0c;一切都是那么顺利&#xff0c;但是有一个问题未解决&#xff0c;就是如果网关配置信息发生变更时如何生效&#xff1f;以及我使用其他数据库存储如何快速实…

计算机提示找不到vcruntime140.dll,无法继续执行代码怎么办?如何修复

“找不到vcruntime140.dll&#xff0c;无法继续执行代码”。这个问题可能会让你感到困惑&#xff0c;不知道如何解决。那么&#xff0c;vcruntime140.dll是什么文件&#xff1f;它为什么会丢失&#xff1f;又该如何解决这个问题呢&#xff1f;本文将为你详细介绍vcruntime140.d…

codeforces1486 F. Pairs of Paths(倍增+树上数数)

F. Pairs of Paths syksykCCC题解 iamhpp题解 首先说明&#xff0c;下面图片来自第一篇博客&#xff0c;下面代码照抄第二篇博客 对没有啥是自己写的&#xff08;因为我太菜~~ 从上图可以看出两条链只有一个交点可能有两种情况 交点是两条链的LCA交点是一条链的LCA而不是另一…

学习Raft算法的笔记

Raft是一种为了管理日志复制的一致性算法。它提供了和Paxos算法相同的功能和性能&#xff0c;但是它的算法结构和Paxos不同&#xff0c;使得Raft算法更加容易理解并且更容易构建实际的系统。为了提升可理解性&#xff0c;Raft将一致性算法分解成几个关键的模块&#xff0c;例如…

.NET Core 必备安全措施

.NET Core大大简化了.NET应用程序的开发。它的自动配置和启动依赖大大减少了开始一个应用所需的代码和配置量&#xff0c;本文目的是介绍如何创建更安全的.NET Core应用程序。1.在生产中使用HTTPS传输层安全性&#xff08;TLS&#xff09;是HTTPS的官方名称&#xff0c;你可能听…

[翻译] C# 8.0 新特性

原文: Building C# 8.0[译注:原文主标题如此&#xff0c;但内容大部分为新特性介绍&#xff0c;所以意译标题为 "C# 8.0 新特性"]C# 的下一个主要版本是 8.0。我们已经为它工作了很长一段时间&#xff0c;即使我们构建并发布了次要版本 C# 7.1, 7.2 和 7.3&#xff0…

[蓝桥杯][2018年第九届真题]搭积木

[[蓝桥杯][2018年第九届真题]搭积木](https://www.dotcpp.com/oj/problem2292.html)题目&#xff1a; 小明对搭积木非常感兴趣。他的积木都是同样大小的正立方体。 在搭积木时&#xff0c;小明选取 m 块积木作为地基&#xff0c;将他们在桌子上一字排开&#xff0c;中间不留空…

使用C#把Tensorflow训练的.pb文件用在生产环境

训练了很久的Tf模型&#xff0c;终于要到生产环境中去考验一番了。今天花费了一些时间去研究tf的模型如何在生产环境中去使用。大概整理了这些方法。继续使用分步骤保存了的ckpt文件这个貌似脱离不了tensorflow框架&#xff0c;而且生成的ckpt文件比较大&#xff0c;发布到生产…

牛客题霸 转圈打印矩阵 C++题解/答案

牛客题霸 转圈打印矩阵 C题解/答案 题目描述 给定一个整型矩阵matrix&#xff0c;请按照顺时针转圈的方式打印它。 示例1 输入 复制 [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] 返回值 复制 [1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10] 题解&#xff1a; 题意很明确…

【招聘(上海)】东方财富证券招聘.net开发

东方财富证券&#xff1a;东方财富网(深创&#xff1a;300059)旗牌照齐全证券公司&#xff0c;极具互联网基因的券商。.Net服务端开发工程师/.Net前端开发工程师[职位介绍]服务端&#xff1a;开户、交易及资讯系统的后端接口服务(Asp.Net WebApi)开发&#xff1b;服务端&#x…

EF Core 实现多租户

SAAS 和多租户SaaS(软件及服务)区别于其他应用程序的主要特征就是能够使客户在使用应用程序时按照使用量付费。他们不需要为软件购买许可&#xff0c;也不需要安装、托管和管理它。这方面的操作全部由提供 SaaS 软件的组织负责。多租户是实现 SaaS 的关键因素, 它可以让多个企业…

牛客题霸 反转链表 C++题解/答案

题目描述 输入一个链表&#xff0c;反转链表后&#xff0c;输出新链表的表头。 示例1 输入 复制 {1,2,3} 返回值 复制 {3,2,1} 题解&#xff1a; 如果用偷懒的方法&#xff0c;可以用vector来存链表内容&#xff0c;然后来个翻转&#xff08;vector自带&#xff09;即可 但是…

【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis

上篇文章【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置&#xff08;2&#xff09;我们介绍了2种网关配置信息更新的方法和扩展Mysql存储&#xff0c;本篇我们将介绍如何使用Redis来实现网关的所有缓存功能&#xff0c;用到的文档及源码将会在GitHub上开源&a…

广州.net俱乐部12月份ABP框架活动场地征集、志愿者征集、合作讲师\副讲师征集...

大家好&#xff0c;我在<被低估的.net(上) - 微软MonkeyFest 2018广州分享会活动回顾>一文中提到&#xff0c;我将在12月份搞一场ABP框架活动&#xff0c;现向大家征集活动场地、志愿者、合作讲师\副讲师。活动课程标题是&#xff1a;如何用ABP框架快速完成项目这是内容大…

CF1446F-Line Distance【计算几何,树状数组,二分】

正题 题目链接:https://www.luogu.com.cn/problem/CF1446F 题目大意 给出nnn个点&#xff0c;求所有点对构成的直线中与原点距离第kkk小的距离 2≤n≤105,1≤k≤n(n−1)22\leq n\leq 10^5,1\leq k\leq \frac{n(n-1)}{2}2≤n≤105,1≤k≤2n(n−1)​ 解题思路 二分还是挺显然的…

为什么是容器,Docker和Kubernetes?

如果你是一名IT行业的从业者&#xff0c;还没有听说过以上3个词的任何一个&#xff0c;抱歉&#xff0c;你可以改行了&#xff1b;如果你是一名技术人员&#xff0c;无论你是程序员&#xff0c;测试人员&#xff0c;运维工程师还是时髦的DevOps工程师&#xff0c;你还没有运行过…

一份来自28岁.NET老程序员的自白

写在前面很幸运&#xff0c;28岁的我头发还没有掉光&#xff0c;更幸运的是28岁的我开始了博客园的写作生活&#xff01;这样的技术分享经历让我拓展了自己的朋友圈&#xff01;有幸结识了像张善友张队&#xff08;连续13年的微软MVP&#xff09;&#xff0c;大石头(NewLife团队…