Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从asp.net核心应用程序C验证文件中的Json对象#_C#_Node.js_Asp.net Core_Cryptojs_Node Crypto - Fatal编程技术网

C# 如何从asp.net核心应用程序C验证文件中的Json对象#

C# 如何从asp.net核心应用程序C验证文件中的Json对象#,c#,node.js,asp.net-core,cryptojs,node-crypto,C#,Node.js,Asp.net Core,Cryptojs,Node Crypto,问题:nodejs应用程序创建一个json文件,该文件是一个许可证,asp.net核心应用程序需要使用公钥验证该信息。节点应用程序使用RSA sha256使用私钥对其进行签名,.net核心应用程序将使用公钥进行验证。非常感谢。json文件包含以下信息: { "info":{ "validto":1514678400000,"validfrom":1498608000000,"nodes":10,"email":"person@example.com","name":"TA

问题:nodejs应用程序创建一个json文件,该文件是一个许可证,asp.net核心应用程序需要使用公钥验证该信息。节点应用程序使用RSA sha256使用私钥对其进行签名,.net核心应用程序将使用公钥进行验证。非常感谢。json文件包含以下信息:

    {
    "info":{
    "validto":1514678400000,"validfrom":1498608000000,"nodes":10,"email":"person@example.com","name":"TAC Account","phone":"3333333333333","address":"something"
    },

"signature":
    {
    "data":[159,1,86,24,244,199,39,40,251,195,175,80,18,33,232,63,178,213,205,129,150,58,243,154,138,168,61,197,222,50,222,80,33,82,135,243,121,250,176,33,9,25,167,177,235,193,246,236,235,19,187,118,57,64,38,143,42,35,12,207,133,33,166,201,34,76,40,87,242,163,141,14,218,198,247,91,191,132,86,162,194,143,177,147,65,171,160,41,2,244,130,53,82,178,72,39,247,45,242,139,243,59,79,196,12,70,14,202,246,48,231,66,38,94,235,237,204,77,40,252,216,63,41,204,210,228,93,16,201,4,123,104,119,251,56,160,9,105,180,217,129,113,19,166,89,199,203,129,47,218,20,131,94,87,251,193,177,111,151,72,187,79,0,63,0,168,36,147,155,47,5,123,176,203,189,111,199,165,90,12,122,2,148,62,107,115,132,183,76,147,7,238,154,174,198,226,170,204,193,18,197,30,191,189,133,134,33,33,159,14,90,153,219,226,184,149,19,179,210,171,136,39,144,178,229,236,126,11,252,80,65,83,181,117,26,37,231,92,151,110,33,93,239,243,129,58,201,214,231,248,151,23,19,170,0,19],
    "type":"Buffer"
    }

    }
我们在asp.net核心端尝试了许多方法,但没有成功,给定的公钥具有一些不寻常的字符,如\n,这是典型的。以下是我们尝试过的不同方法之一:

using System ;
using System.IO ;
using System.Text ;
using Org.BouncyCastle.Crypto ;
using Org.BouncyCastle.Crypto.Parameters ;
using Org.BouncyCastle.OpenSsl ;
using Org.BouncyCastle.Security ;

namespace ValidateRsa
{
    internal class Program
    {
        private static readonly string info =
                @"{""validto"":1514678400000,""validfrom"":1498608000000,""nodes"":10,""email"":""person@example.com"",""name"":""TAC Account"",""phone"":""3333333333333"",""address"":""something""}"
            ;
        private static readonly byte[] signature =
        {
            159, 1, 86, 24, 244, 199, 39, 40, 251, 195, 175, 80, 18, 33, 232, 63, 178, 213, 205, 129, 150, 58, 243, 154, 138, 168,
            61, 197, 222, 50, 222, 80, 33, 82, 135, 243, 121, 250, 176, 33, 9, 25, 167, 177, 235, 193, 246, 236, 235, 19, 187, 118,
            57, 64, 38, 143, 42, 35, 12, 207, 133, 33, 166, 201, 34, 76, 40, 87, 242, 163, 141, 14, 218, 198, 247, 91, 191, 132, 86,
            162, 194, 143, 177, 147, 65, 171, 160, 41, 2, 244, 130, 53, 82, 178, 72, 39, 247, 45, 242, 139, 243, 59, 79, 196, 12,
            70, 14, 202, 246, 48, 231, 66, 38, 94, 235, 237, 204, 77, 40, 252, 216, 63, 41, 204, 210, 228, 93, 16, 201, 4, 123, 104,
            119, 251, 56, 160, 9, 105, 180, 217, 129, 113, 19, 166, 89, 199, 203, 129, 47, 218, 20, 131, 94, 87, 251, 193, 177, 111,
            151, 72, 187, 79, 0, 63, 0, 168, 36, 147, 155, 47, 5, 123, 176, 203, 189, 111, 199, 165, 90, 12, 122, 2, 148, 62, 107,
            115, 132, 183, 76, 147, 7, 238, 154, 174, 198, 226, 170, 204, 193, 18, 197, 30, 191, 189, 133, 134, 33, 33, 159, 14, 90,
            153, 219, 226, 184, 149, 19, 179, 210, 171, 136, 39, 144, 178, 229, 236, 126, 11, 252, 80, 65, 83, 181, 117, 26, 37,
            231, 92, 151, 110, 33, 93, 239, 243, 129, 58, 201, 214, 231, 248, 151, 23, 19, 170, 0, 19
        } ;
        private static void Main (string[] args)
        {
            Console.WriteLine ("Setting up validator...") ;
            TextReader text = File.OpenText (@"X:\Scratch\pubkey.asc") ;
            var pemr = new PemReader (text) ;
            object pem = pemr.ReadObject () ;
            text.Close () ;
            var keyParams = (RsaKeyParameters) (AsymmetricKeyParameter) pem ;
            ISigner sig = SignerUtilities.GetSigner ("SHA-256withRSA") ;
            sig.Init (false, keyParams) ;
            byte[] infoBytes = Encoding.ASCII.GetBytes (Program.info) ;
            sig.BlockUpdate (infoBytes, 0, infoBytes.Length) ;
            if (sig.VerifySignature (Program.signature))
                Console.WriteLine ("Verified!") ;
            else
                Console.WriteLine ("Failed!") ;
            Console.ReadLine () ;
        }
    }
}
公钥采用以下格式:

 -----BEGIN RSA PUBLIC KEY
-----\nMIIBCgKCAQEAqao1ZkAYKDybHSeoy79ySQDcXODByDRaZKT2nYwT8GrYohBle8phB5LgSoQu\nVD7ErRFGHxutcqPrfL3AuTHg874Kmw6/G+25/FdC9uNJzLtCP+Z5mOrF5HlU8dGOOpTeq4y5\n0EPcj//YuO4kScj0wOOp1HMRwxsdVo\nAZUQwMz5w1QIoGL5CoW7RKiL/oQw0Mh0Ju+9ofVbovSzBTo0r7onqw6M0hOJScV86iQ21Ukl\nup/6CmXCMwcYK1Fr5J6YNbeZoQhkII7VazPMgZetJBCfm+iyBPSPARlf13RLM0cHzwIDAQAB\n-----END RSA PUBLIC KEY-----\n
nodejs应用程序对数据进行签名的代码:

 const licenseSchema = new Schema({
  info: {
    name: String,
    address: String,
    phone: String,
    email: String,
    nodes: Number,
    validfrom: Schema.Types.Mixed,  // validfrom and validto must be either
    validto: Schema.Types.Mixed,    // valid Date strings or ms since epoch
  },

  signature: {
    type: { type: String, required: true },
    data: { type: Schema.Types.Mixed, required: true },
  },
});

// updates license.signature
licenseSchema.statics.createAndSignLicense = function createAndSignLicense(object, privateKey, cb) {
  let arrayInfo = [];
  arrayInfo = [
    object.name,
    object.address,
    object.phone.toString(),
    object.email,
    object.nodes.toString(),
    object.validfrom,
    object.validto,
  ];
  const sign = crypto.createSign('RSA-SHA256');
  sign.update(JSON.stringify(arrayInfo));
  const sig = sign.sign(privateKey);

  const LicenseModel = this;

  const licenseDoc = new LicenseModel({
    info: object,
    signature: {
      type: 'Buffer',
      data: Array.prototype.slice.call(sig, 0),
    },
  });

  licenseDoc.save((err) => {
    if (err) { return cb(err); }

    return cb(null, licenseDoc);
  });
};
还有另一个nodejs应用程序正在成功验证数据,示例如下,仅在.net中,情况并不一致:

    const Schema = mongoose.Schema;

export const Errors = {LicenseValidationError: 'LicenseValidationError'};

const LicenseDescription = {
    key: { type: String, unique: true },
    info: {
        name: String,
        address: String,
        phone: String,
        email: String,
        nodes: Number,
        validfrom: Schema.Types.Mixed,  // validfrom and validto must be either
        validto: Schema.Types.Mixed,    // valid Date strings or ms since epoch
    },
    signature: {
        type: { type: String, required: true },
        data: Schema.Types.Mixed
    }
};

// Application state variable representing license validity.
let isLicenseValid = false;

/*
 * uses the utils function with a validator to set the system-wide document
 * license is a file (buffer) or JSON license.
 * This method attempts to validate the input.
 *
 * See: License.statics.ValidateLicense()
 *
 * cb: function (err, license) { ... }
 */
const License = utils.createSchema(LicenseDescription, {
    validator: function (license, cb) {
        validateLicense(license, (err, valid) => {
            if (err) {
                return cb(err);
            }
            isLicenseValid = isLicenseWithinDateRange(license);
            return cb(null, true);
        });
    }
});


// license public key, hardcoded.
// Uses RSA-SHA256
    const pair = () => ({
    public: `-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAqao1ZkAYKDybHSeoy79ySQDcXODByDRaZKT2nYwT8GrYohBle8phB5LgSoQu\nVD7ErRFGHxutcqPrfL3AuTHg874Kmw6/G+25/FdC9uNJzLtCP+Z5mOrF5HlU8dGOOpTeq4y5\n0EPcj//YuO4kScj0wOOp1HMRwxsdVo+G00Q\nAZUQwMz5w1QIoGL5CoW7RKiL/oQw0Mh0Ju+9oV86iQ21Ukl\nup/6CmXCMwcYK17VazPMgZetJBCfm+iyBPSPARlf13RLM0cHzwIDAQAB\n-----END RSA PUBLIC KEY-----\n`
});

/*
 * Verifies the supplied license (must be a valid JSON object) against the
 * public key (hardcoded).
 *
 * Returns true if valid, false otherwise.
 */
const verifySignature = license => {
    winston.info('Verifying license signature:');

    // crypto.verify relies on specific key ordering (undefined behavior, unfortunately).
    // To try to force key order, we construct this object (with explicit toString calls
    // where applicable).
    const infoString = [
        license.info.name,
        license.info.address,
        license.info.phone,
        license.info.email,
        license.info.nodes.toString(),
        new Date(license.info.validfrom).toString(),
        new Date(license.info.validto).toString(),
    ];

    const infoMS = [
        license.info.name,
        license.info.address,
        license.info.phone,
        license.info.email,
        license.info.nodes.toString(),
        license.info.validfrom,
        license.info.validto,
    ];

    const verifyString = crypto.createVerify('RSA-SHA256'), verifyMS = crypto.createVerify('RSA-SHA256'), 
    licenseInfoString = JSON.stringify(infoString), licenseInfoMS = JSON.stringify(infoMS);

    // Currently the signature must be a buffer and the type field is ignored.
    let buf;
    try {
        buf = new Buffer(license.signature.data);
    } catch (parseError) {
        return false;
    }

    verifyString.update(licenseInfoString);
    verifyMS.update(licenseInfoMS);

    const isLicenseValid = verifyString.verify(pair().public, buf) || verifyMS.verify(pair().public, buf);
    winston.info(`The license signature is ${(isLicenseValid) ? 'valid.' : 'invalid.'}`);
    return isLicenseValid;
};

我想你的钥匙文件有问题吧

您的代码运行良好

以下是在节点中生成签名的示例:

var crypto = require('crypto');
var fs = require('fs');

var privateKey = fs.readFileSync('./junk').toString('utf8');
var publicKey = fs.readFileSync('./junk.pem').toString('utf8');

var sign = crypto.createSign('RSA-SHA256');
sign.update("Test123");
var sig = sign.sign(privateKey);
var bytes = Array.prototype.slice.call(sig, 0);
console.log(JSON.stringify(bytes));

var verify = crypto.createVerify('RSA-SHA256');
verify.update("Test123");
var success = verify.verify(publicKey, new Buffer(sig));

console.log("Did sign? " + success);
下面是一个使用C#.net内核中的bouncy castle验证它的示例(我已经简化了,但基本上就是您正在做的):

我刚刚随机生成了这两个关键文件:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA1I++ulXUpZUopjSe7M74PJpj0D9JbbpV3MChYvqnu1m9+Rnd
5fr1FUg7xQu+EI0XN+YIi9CbZl4tGtxjela00MidM2dd1BI/5W2Zl4DHnPPmvfZo
ybBquK6dwkkTe5AhCCZegYD4TsNhKWGqea8DfSiCAvTeG0uiXbQGPD6lWei3IoVc
OQ0cuz3LheCl440Bbmg2BVMUrZO81r6yH1Nz0ypYnBfx26Mo7379ngHc3yjxi8vj
DF/is4wqOgWj34R3gbbf9EZ5OWS+DpItPpFZYkh82DrNHNCPSyvD0XvmcPhJ6O7y
rloAPSiTUP9+u7w1zBpg50Srcp+afUcGODYmKQIDAQABAoIBAChRh7zycN5jl41H
J+oFLCLaqhojFvuAP68avsH2h4BK+nTYijWIT5qU0/mBS7D6AjBxKqfSjtdw/587
tIbNEYkUtHS+o5aJS6NqEZsiKzrDLL5VkfTHyMZ1IKlskQx7/zf7hyuLWg4ekzx1
MQ/ZuZCw8VA8QDDvPMIHVrNwso6F8/vc/K3tqygeFBh+rfAbkzp2zvK4Tr+reJTT
hmsg68wBzTNAzmeHK8FsMB2NZvwW/zq5ZgEIkZVkJZl7XbYGj+ggVSn2h0J8KleK
H+60nx39wk/KnscsHo9lPpv/7RoYb7OGEVR8W0fY5+QvALTZ8U9HZftm9TfhUd/0
Is5CIT0CgYEA/kaqLKK2hYlEdP2f9N6w/qiF2Gmxu6N1Tk+gvbz1ChukPHW42xUz
iG45So6iGDWNzjVf9IxAP2n0Zltar4tMlyC767jk5Xs7kONZMwqge5a52NYLRRvt
xoklLgXCjurriq+hw6tNAuvVjs/ScOHOQyC4emVDqJ5Z9766zqrpkCsCgYEA1gCt
pGAwt5KoDOXlk3311BDS6XLev536GW25CmKrs9sJH2cOWSRFA0fWcPr0gVotM9F5
+2ymmJmlYLLDRYWTYCX+vL8aysTTDqezpOhJ9VIzgeTh3FwD17LFE5j4W0AqE5jR
2eMItfobMYqHF4iHp+OmfhocLpLQcTC4BlMvZPsCgYBLXOZTFGbEbUq84e7mxJnw
4EHLQohK9Mdvzmn10mtN86NZyAph5IbBiOmyD1Q7mKPO2kL2WBsysFSfgbP/E2o/
4JPR6Zrt6PhemQN2/U9TUfkDK21rrjtq/HroiQyBD1+AW022kK7ijsNc8HuOuV5I
xwnmPN0wvL4tj3oOhtlywQKBgAsXq+h6R+wsAOPyQq0beVONr7EEEEG0aZNJ2a6N
IMNI1jc3e0nplF4wKhBfIa9WwkMOV5lNr3D3fdf+TBrdap8wOP0FltjtzNbUoH4q
wDKkGSFhgMeQSW6zyH1Uj4MDV2r+n9oAZ6IvHZu6x3fTztxH84hTyCQt3foQAWnq
g+ljAoGBAMza/hD+Hsz7uNtVvvqki6a6FMk7cSZTEtZvBvqrywIEEZEnbsuHk5tD
towaZbQQirZp45xsEJZDO/8O5Q0+WEs/0ZG1CPBgIwNEBUt/deid6s1HFFoESp0/
DfekILO1scieEpccfz8aIlgq/CoRFfXQ5m0VetfP6H6Wau1Hfx5A
-----END RSA PRIVATE KEY-----
以及:

…而且效果很好:

$ node test
[193,185,118,187,54,28,71,173,185,255,213,61,254,51,86,168,224,11,113,23,81,123,89,31,89,183,142,194,7,250,194,165,230,254,74,61,15,12,137,246,151,61,83,107,112,178,98,183,234,247,56,11,246,179,183,74,27,190,17,99,161,31,209,178,81,41,56,214,184,165,232,20,125,155,25,102,104,193,1,101,143,209,192,145,47,215,190,95,196,164,69,203,206,69,142,18,196,155,221,8,31,179,5,165,143,29,34,148,218,177,94,31,174,218,153,52,85,156,67,2,157,29,111,95,231,249,212,39,123,229,75,2,18,238,44,94,181,181,98,156,150,44,219,208,161,18,250,117,91,146,133,233,210,161,133,233,228,111,124,107,96,134,123,148,88,238,193,50,216,187,42,131,51,28,52,55,150,31,49,95,63,245,58,212,205,26,223,32,124,233,20,148,107,33,162,47,107,221,238,221,200,89,199,52,164,114,177,254,146,60,118,1,78,73,231,138,136,201,242,26,100,57,237,135,181,44,193,143,191,155,93,66,142,69,203,57,22,147,120,161,117,167,54,16,200,6,27,160,187,15,197,138,201,114,52,202]
Did sign? true
$ dotnet run
True
那我猜呢

要么您的公钥有问题,要么由于某种原因,您传递给两边函数的json输入不完全相同


据我所知,您的签名代码没有问题。

首先,感谢您的时间和努力。是的,看起来像是带有公钥的东西,它在开始和结束时有额外的RSA,然后\n但是签名节点应用程序和验证节点应用程序似乎没有任何问题。我会调查的。为什么节点公钥采用这种格式,我没有看到过这种公钥。上面的公钥格式是PEM格式,与您的示例中相同。如果您有一个格式为“ssh rsa ASFASDFDFFDSSDFDFDF…”的密钥,您可能需要转换它?请参阅(node crypto library将同时使用这两种方法;它足够智能,可以自动检测格式)我对公钥包含的“\n”部分感到困惑,是否可以?该\n部分很好;在您的评论中,键是ok。。。但在代码中使用:
X:\Scratch\pubkey.asc
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1I++ulXUpZUopjSe7M74
PJpj0D9JbbpV3MChYvqnu1m9+Rnd5fr1FUg7xQu+EI0XN+YIi9CbZl4tGtxjela0
0MidM2dd1BI/5W2Zl4DHnPPmvfZoybBquK6dwkkTe5AhCCZegYD4TsNhKWGqea8D
fSiCAvTeG0uiXbQGPD6lWei3IoVcOQ0cuz3LheCl440Bbmg2BVMUrZO81r6yH1Nz
0ypYnBfx26Mo7379ngHc3yjxi8vjDF/is4wqOgWj34R3gbbf9EZ5OWS+DpItPpFZ
Ykh82DrNHNCPSyvD0XvmcPhJ6O7yrloAPSiTUP9+u7w1zBpg50Srcp+afUcGODYm
KQIDAQAB
-----END PUBLIC KEY-----
$ node test
[193,185,118,187,54,28,71,173,185,255,213,61,254,51,86,168,224,11,113,23,81,123,89,31,89,183,142,194,7,250,194,165,230,254,74,61,15,12,137,246,151,61,83,107,112,178,98,183,234,247,56,11,246,179,183,74,27,190,17,99,161,31,209,178,81,41,56,214,184,165,232,20,125,155,25,102,104,193,1,101,143,209,192,145,47,215,190,95,196,164,69,203,206,69,142,18,196,155,221,8,31,179,5,165,143,29,34,148,218,177,94,31,174,218,153,52,85,156,67,2,157,29,111,95,231,249,212,39,123,229,75,2,18,238,44,94,181,181,98,156,150,44,219,208,161,18,250,117,91,146,133,233,210,161,133,233,228,111,124,107,96,134,123,148,88,238,193,50,216,187,42,131,51,28,52,55,150,31,49,95,63,245,58,212,205,26,223,32,124,233,20,148,107,33,162,47,107,221,238,221,200,89,199,52,164,114,177,254,146,60,118,1,78,73,231,138,136,201,242,26,100,57,237,135,181,44,193,143,191,155,93,66,142,69,203,57,22,147,120,161,117,167,54,16,200,6,27,160,187,15,197,138,201,114,52,202]
Did sign? true
$ dotnet run
True