简体   繁体   English

如何从 Flutter 中的 RSA 私钥生成令牌?

[英]How to generate a token from a RSA private key in Flutter?

Hi Guys I am really confused about so many things.All I know is that I have to generate a token at the end of the day.I am given some RSA private key which is some "XYZ............dsdsfm",(obviously I can't reveal it because of security issues),from there I have to generate some token which will serve as a header for authorisation of my API http request.嗨,伙计们,我真的对很多事情感到困惑。我所知道的是我必须在一天结束时生成一个令牌。我得到了一些 RSA 私钥,它是一些“XYZ ......... ...dsdsfm”,(显然由于安全问题我不能透露它),从那里我必须生成一些令牌,它将作为我的 API http 请求授权的标头。

The problem is these internet related stuff of JsonWebKey and all that is not in my domain,but still I tried learning them but it is not very clear.I tried to implement some code which was written in Java by someone (and that guy knows only Java and not flutter),in flutter.问题是 JsonWebKey 的这些互联网相关的东西以及所有不在我的领域中的东西,但我仍然尝试学习它们,但不是很清楚。我尝试实现一些由某人用 Java 编写的代码(而那个人只知道Java 而不是颤振),在颤振中。

For Flutter implementation I tried two plugin in pub.dev...But I am not getting the proper output.对于 Flutter 实现,我在 pub.dev 中尝试了两个插件......但我没有得到正确的输出。

The first one was https://pub.dev/packages/jose>I tried what is similar in the example page of it as shown:第一个是https://pub.dev/packages/jose>我在它的示例页面中尝试了类似的内容,如下所示:

import 'dart:convert';
import 'dart:io';

import 'package:crypto_keys/crypto_keys.dart';
import 'package:jose/jose.dart';
import 'package:x509/x509.dart';

String pkey="XXXXXXXXXXXXXsfds";

void keyGenerator() async {
 //await example1();
  await example2();
//  await example3();
//  await example4();
//  await example5();
 // await example6();
//  await example7();
//  await example8();
}

// decode and verify a JWS
void example1() async {
  var encoded = pkey;

  // create a JsonWebSignature from the encoded string
  var jws = JsonWebSignature.fromCompactSerialization(encoded);

  // extract the payload
  var payload = jws.unverifiedPayload;

  print('content of jws: ${payload.stringContent}');
  print('protected parameters: ${payload.protectedHeader.toJson()}');

  // create a JsonWebKey for verifying the signature
  var jwk = JsonWebKey.fromJson({
    'kty': 'RSA',
    'alg': 'RS256',

  });
  var keyStore = JsonWebKeyStore()..addKey(jwk);

  // verify the signature
  var verified = await jws.verify(keyStore);
  print('signature verified: $verified');
}

// create a JWS
void example2() async {
  // create a builder
  var builder = JsonWebSignatureBuilder();

  // set the content
  builder.stringContent = 'It is me';

  // set some protected header
  builder.setProtectedHeader('createdAt', DateTime.now().toIso8601String());

  // add a key to sign, you can add multiple keys for different recipients
  builder.addRecipient(
      JsonWebKey.fromJson({
        'kty': 'RSA',
        'kid': pkey,
      }),
      algorithm: 'RS256');

  // build the jws
  var jws = builder.build();

  // output the compact serialization
  print('jws compact serialization: ${jws.toCompactSerialization()}');

  // output the json serialization
  print('jws json serialization: ${jws.toJson()}');
}

// decode and decrypt a JWE
void example3() async {
  var encoded = 'eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.'
      'UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm'
      '1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc'
      'HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF'
      'NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8'
      'rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv'
      '-B3oWh2TbqmScqXMR4gp_A.'
      'AxY8DCtDaGlsbGljb3RoZQ.'
      'KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.'
      '9hH0vgRfYgPnAHOd8stkvw';

  // create a JsonWebEncryption from the encoded string
  var jwe = JsonWebEncryption.fromCompactSerialization(encoded);

  // create a JsonWebKey for decrypting the signature
  var jwk = JsonWebKey.fromJson(
    {
      'kty': 'RSA',
      'n': 'sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl'
          'UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre'
          'cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_'
          '7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI'
          'Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU'
          '7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw',
      'e': 'AQAB',
      'd': 'VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq'
          '1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry'
          'nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_'
          '0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj'
          '-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj'
          'T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ',
      'p': '9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68'
          'ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP'
          'krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM',
      'q': 'uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y'
          'BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN'
          '-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0',
      'dp': 'w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv'
          'ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra'
          'Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs',
      'dq': 'o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff'
          '7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_'
          'odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU',
      'qi': 'eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC'
          'tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ'
          'B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo'
    },
  );
  var keyStore = JsonWebKeyStore()..addKey(jwk);

  // decrypt the payload
  var payload = await jwe.getPayload(keyStore);
  print('decrypted content: ${payload.stringContent}');
}

// create a JWE
void example4() async {
  // create a builder
  var builder = JsonWebEncryptionBuilder();

  // set the content
  builder.stringContent = 'This is my bigest secret';

  // set some protected header
  builder.setProtectedHeader('createdAt', DateTime.now().toIso8601String());

  // add a key to encrypt the Content Encryption Key
  var jwk = JsonWebKey.fromJson(
    {
      'kty': 'RSA',
      'n': 'sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl'
          'UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre'
          'cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_'
          '7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI'
          'Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU'
          '7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw',
      'e': 'AQAB',
      'd': 'VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq'
          '1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry'
          'nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_'
          '0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj'
          '-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj'
          'T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ',
      'p': '9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68'
          'ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP'
          'krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM',
      'q': 'uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y'
          'BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN'
          '-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0',
      'dp': 'w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv'
          'ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra'
          'Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs',
      'dq': 'o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff'
          '7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_'
          'odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU',
      'qi': 'eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC'
          'tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ'
          'B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo'
    },
  );
  builder.addRecipient(jwk, algorithm: 'RSA1_5');

  // set the content encryption algorithm to use
  builder.encryptionAlgorithm = 'A128CBC-HS256';

  // build the jws
  var jwe = builder.build();

  // output the compact serialization
  print('jwe compact serialization: ${jwe.toCompactSerialization()}');

  // output the json serialization
  print('jwe json serialization: ${jwe.toJson()}');
}

// decode and verify and validate a JWT
void example5() async {
  var encoded = 'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.'
      'eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt'
      'cGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
      'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk';

  // decode the jwt, note: this constructor can only be used for JWT inside JWS
  // structures
  var jwt = JsonWebToken.unverified(encoded);

  // output the claims
  print('claims: ${jwt.claims}');

  // create key store to verify the signature
  var keyStore = JsonWebKeyStore()
    ..addKey(JsonWebKey.fromJson({
      'kty': 'oct',
      'k':
      'AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow'
    }));

  var verified = await jwt.verify(keyStore);
  print('verified: $verified');

  // alternatively, create and verify the JsonWebToken together, this is also
  // applicable for JWT inside JWE
  jwt = await JsonWebToken.decodeAndVerify(encoded, keyStore);

  // validate the claims
  var violations = jwt.claims.validate(issuer: Uri.parse('alice'));
  print('violations: $violations');
}

// create a JWT
void example6() async {
  var claims = JsonWebTokenClaims.fromJson({
    'exp': Duration(hours: 4).inSeconds,
    'aud':"live-tv",
    'iat':DateTime.now().toString(),

  });

  // create a builder, decoding the JWT in a JWS, so using a
  // JsonWebSignatureBuilder
  var builder = JsonWebSignatureBuilder();

  // set the content
  builder.jsonContent = claims.toJson();

  // add a key to sign, can only add one for JWT
  builder.addRecipient(
      JsonWebKey.fromJson({
        'kty': 'RSA',
        'kid':pkey,
         }),

      algorithm: 'HS256');

  // build the jws
  var jws = builder.build();

  // output the compact serialization
  print('jwt compact serialization: ${jws.toCompactSerialization()}');
}

// create a JWT, sign with RS512
void example7() async {
  var claims = JsonWebTokenClaims.fromJson({
    'exp': Duration(hours: 4).inSeconds,
    'iss': 'alice',
  });

  // create a builder, decoding the JWT in a JWS, so using a
  // JsonWebSignatureBuilder
  var builder = JsonWebSignatureBuilder();

  // set the content
  builder.jsonContent = claims.toJson();

  // add a key to sign, can only add one for JWT
  var key = JsonWebKey.fromPem(File('example/jwtRS512.key').readAsStringSync());
  builder.addRecipient(key, algorithm: 'RS512');

  // build the jws
  var jws = builder.build();

  // output the compact serialization
  print('jwt compact serialization: ${jws.toCompactSerialization()}');
}

// generate a key for use with ES256 signing
void example8() async {
  var alg = JsonWebAlgorithm.getByName('ES256');

  var key = alg.generateRandomKey();
  print(JsonEncoder.withIndent(' ').convert(key));

  final hash = utf8.encode('TEST');

  var sig = key.sign(hash);
  final valid = key.verify(hash, sig);

  print('valid? $valid');
}

I tried each example at a time modifying each of those.Few of them said saying "Compact serialisation should have 3 parts",then I did a bit of research and realised that the token to be generated should have 3 parts.The other error in example 2 was that the JSONWebKey can't be signed.我一次尝试了每个示例,修改了每个示例。很少有人说“紧凑序列化应该有 3 个部分”,然后我做了一些研究并意识到要生成的令牌应该有 3 个部分。另一个错误是示例 2 是 JSONWebKey 无法签名。

There is another library I used and that was https://pub.dev/packages/corsac_jwt .我使用了另一个库,它是https://pub.dev/packages/corsac_jwt

The code is below:代码如下:

import 'package:corsac_jwt/corsac_jwt.dart';
//  ..setClaim('13', {'userId': 'xxxx'})

String pkey="sdfdsfdsfds";

void tokenGenerator() {

  var builder = new JWTBuilder();
  var token = builder
    ..audience="live-tv"
    ..issuedAt= new DateTime.now()
    ..expiresAt = new DateTime.now().add(new Duration(minutes: 3))

    ..getToken(); // returns token without signature

 var signer = new JWTRsaSha256Signer(privateKey: pkey);

  var signedToken = builder.getSignedToken(signer);
  print("token");
      print(signedToken); // prints encoded JWT
  var stringToken = signedToken.toString();

  var decodedToken = new JWT.parse(stringToken);
  // Verify signature:
  print(decodedToken.verify(signer)); // true

  // Validate claims:
//  var validator = new JWTValidator() ;// uses DateTime.now() by default
//   // set claims you wish to validate
//  Set<String> errors = validator.validate(decodedToken);
//  print(errors); // (empty list)
}

But here I got the error invalid private key.If I changed it to public,I got invalid public key as well.但是在这里我得到了无效私钥的错误。如果我将其更改为 public,我也会得到无效的公钥。

I honestly am I a very chaotic situation mentally with time running out to implement.My team mates are know only one thing I know only flutter only.老实说,我是一个精神上很混乱的情况,时间不多了。我的队友只知道一件事,我只知道颤抖。

By the way the Java code we are trying to implement in flutter is given below.Basically what it does is it takes a StringKey,converts to a PrivateKey and then the token顺便说一下,下面给出了我们试图在 flutter 中实现的 Java 代码。基本上它的作用是它需要一个 StringKey,转换为一个 PrivateKey,然后是令牌

import android.util.Log;

import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;
import java.util.concurrent.TimeUnit;


public class RSAKeyGenerator {
    private static PrivateKey getPrivateKey() throws GeneralSecurityException {
        String pKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
        KeyFactory kf = KeyFactory.getInstance("RSA");
        byte[] decode;
        decode = android.util.Base64.decode(pKey, android.util.Base64.DEFAULT);
        PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(decode);
        return kf.generatePrivate(keySpecPKCS8);
    }
    public static String getJwtToken() {
        final long VALIDITY_MS = TimeUnit.MINUTES.toMillis(60);
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        Date exp = new Date(nowMillis + VALIDITY_MS);
        PrivateKey privateKey = null;
        try {
            privateKey = getPrivateKey();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        String jws = Jwts.builder()
                .claim("version", "13")
                .claim("user_id", "xxxxxxxxxxxxxxxxxxx")
                .setIssuedAt(now)
                .setExpiration(exp)
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .setAudience("live-tv")
                .compact();
        Log.d("111__", jws);
        SpUtil.Companion.getInstance().putString(J_TOKEN, jws);
        return jws;
    }
}

After hours of research,trial and errors and consulting my team mates I have arrived at the final conclusion.This works.The mistake I was doing was the RSA key I was passing it as a string like key="xxxxxxxxxxxx",but it should be in the format below经过数小时的研究、尝试和错误并咨询我的队友,我得出了最终结论。这是有效的。我犯的错误是我将 RSA 密钥作为字符串传递给它,例如 key="xxxxxxxxxxxx",但它应该格式如下

Hope this helps someone希望这有助于某人

import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';

String token;

String dartJsonWebTokenGenerator() {
  Duration delay = new Duration(minutes: 300);
  final jwt = JWT(
    payload: {
      'version': '13',
      'user_id': 'xxxxxxxxxxxxxxxxx',
    },
    audience: 'live-tv',
  );

// Sign it (default with HS256 algorithm)
  token = jwt.sign(PrivateKey('''-----BEGIN RSA PRIVATE KEY-----
                      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7
                      wIxAoKDcHD7mv2R//I0QncGzT1I7cccrhIUB1gXH9wWdTXrafhACXrJ2Drfjg/YN
                      9q4TiKH1k2+zTfdU1IDxd6OX2cPNkwn/vpZeZ1pZqVoimRRJbJg8RhXYvZgd6Nfj
                      Zdw6LY3Zzm3XbLbTUmbVM5ARDweksnr6cg7HmR2OQ5j5UFuhRyIUTSCDbAmDeyHS
                      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx70YmgZPR
                      PIncbKBjLzQe5RB/szyswCAiLxfk7rCrUhPpvdJ4fnDgdXQE26t/CBFb8fpOHtiL
                      1FtxgURmX/Nh+OhO7pPvK4X7g2GarMdQ3Y6288/STQu/d8yEQDwcro6X9ribay46
                      Ss69AGJxGJbazUI9fNMETLpR6kIHKli7G7gtTFVY02YPKpqgYs1HFbIgV++gHTaw
                      XLU3PqroxKkhTuI8JCei1pphS/PAc3S/o0mPxTYLfiojYG/6IDd8WsGonwwk2hqd
                      e3ad0S56JZNN812vshc8NFMbEU2UzA7L0INf6X+GAhoZojUjZciKwAN/iF9YV0cU
                      XorRDXcXrXn7hpqAzDq/jMQO78jr2MyaY/dfiSVp6sTS8gNMCuz0g3I7gSkCAwEA
                      AQKCAgEAiPWqK/qdrFYR4unJwU9ouonlMWGl0BAndIUEcjIt4cPCVwtfuL+aE98q
                      J8MJYINVTgaJ7VbnKnSkARQkuUYWCLhYF8z9hq+h3Ce2QPJMhwC1GCT3MFGMQQRD
                      wP/U8q99k9xljOAckw6TnxjTFJCoFUQrbA9QcXb9ypSMvvorMDGzR+5X99IMsGFj
                      elwJJS4v7fV3oWZsoMcfAcuFlrAETNPjkaX0CmaIru/CaMupq7YQUa6CmMhwQwUJ
                      p/V+aD9OdndhGmTVtHvDq0bew8wHCLxKdQCOUjzHx9Itli1zUthbaZDKkuoH1cyR
                      JyoVkCJ5FV6y5ShN8KzF7UXzZqaEMrTRNF42O1w933CWj3Pm1+PQdHQJXeMvOtWv
                      QTjd1+OtDckREA5W8oiuPnF+RtTHpzXjPtnLNf5yszq2HOkFplqLmLhkN2GDqQib
                      8DjIo+tyF3yHKuVOya21JC1SYDO412nh3GzbttASBcfeas+6v75gB8Eb4IKRO7mj
                      HaN5BGf/XKORp6v95pTv2OAPqnvIimLOe6TNzlPoVedK90CwPwHEan/ooFZI9b9j
                      UlMLynJHQo6rSvmzoa5d1QuEcAjHVJdjfmvXeQaZs3o1Ajk/HbNBrV3Gr69CcHDO
                      vd960cvRZS/9oNloUdzT/3fOND+6DU/iDrTd1TVWt9nfBb9njv0CggEBAPChGrzL
                      s5xLhoh4Ogr6FQZcCvaURhtRI7jz4WrF8dVVtlwTbZSRn1fSCCwwm3lnGRTMZrzh
                      SYzFgzZ753MQPREm+46Swpe8N6XsMFYubmlhAEK8Z7MgJLwKswadxBsMEj7dqPBu
                      1Fezx9vFZO79MNFAzVBS74mXfLC7NVfIZe+Id53RzoDF5t8rGlo4owxRAySRllJU
                      F2UQrBMRf21aqvvdwJSWiFsCuJ2VJTE/N2iS9A6ISdvYWO+ZJPPqffRmpt6T3tIB
                      uOnf4LG1MSG1UyHpQ15BErwJ6M3CMRzRnjlhtI87xXOXsD39QOTd5QnwXETUYGRi
                      Yvj0JmozTlXCCQMCggEBAOqzcuIdix5kvU871T0m1vpMXYIA5+0NolqW/PNQYzQj
                      f55Kwyzlx6BNBKxCvgCoo9YYKRWKq0wN1H0CUvOFxBwu4h/XJqDtc6yM58UYImTG
                      ZWFVJI4GvB0jdTw3F4LMOnEgl2zMQB17Yf7p2WUIFpUowQC5ZEvFa16cYMKRCoPz
                      4RH1p83eDEok2XQSHlZH1hZHG6YlBlMiBPW0904xICnm8dT73jTijaNKrlV5E9FQ
                      IS0tl3Gc6aVEdd/r89ArHYByjRdLN3IXzy8BOLGFtT8/+PB7egdUPEejTNiIGKWo
                      hvWVp6wEyjdOh+zI1X4L1oVXqxBVajTSFk0qxqW2V2MCggEAJK4KK1lJybthiI/7
                      GQ1CAzQon6m+fg+CSIE0jVgbIw/rumFjxM/l4Dct8759FKZ4lkkKKCSXV5QMClQc
                      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxW
                      Qq/prxwXr/TUer7SzQXcfcMYdsjwougGeG6yYLZrT/FuOURoHDztEyOqZUeDU2zJ
                      Zdv6UGZfIsdHhcgGaE8B2l3ujkxIU6bGy3JRLETF80B9brHvIeKchpqom037LFuY
                      X7EKORMbp9R3jJ5eFG9TmTcCzXBtW6Aa2yH2RZzDNZ/1d+xhxEQzZVnyCEz/RhUI
                      Dd6EDQKCAQEAmpjDpt/xAH85F9UAvDw2RT9CJN016Dcf524nhppADlsHuBvk/lEJ
                      MrUoy9NW1pY+/UqC3XavKPS/L+z0+QX2zN2xA2o0PrLKjDFwhapFFX59zyRHZOpY
                      xRTTJ2vep8ChCl1+gSL1ZLYeMcyV72/peC0VHMYBo8uR0wtMzTy+4XYmni7jbr7B
                      96DYQBWjOBAvnBMQylr/FImHHNYsRKwlVJSUXUfe8ZT92T7bIOAVRr3ybJDofeTv
                      Hna+8lW5DzknQLGz8FESX6wBRCQY1Q6O+e/IqZecJPG+ly2g88yJ96zP4TrH7I5n
                      KREohbcwsctYbhL2UlcBE3QDTqdLnGJEowKCAQBwlBtw/BD5cefTcUB90XtuUpLG
                      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                      moP4L4wBlad2aZYKnkZ87RZIa09wyf5hnPXQkQAHMRYxuaxvQUq/bSDO6JUbrGMp
                      J2LQgCreNAF7MsIDU2ijVHJNWp9m6LC1Osb1iMp/fZDy+hkAAHP5xDfDedwKmXLV
                      2kSdWPZebq1iIRyJ+BlbXAEgDMkp+k6mebq+kyH4+3odWvw8bRkmD/g1t/bS
                      -----END RSA PRIVATE KEY-----'''),
      algorithm: JWTAlgorithm.RS256, expiresIn: delay);
  print('Signed token: $token\n');
  return token;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM