腾讯云COS和阿里云OSS签名算法的dart实现

发布于 2022-11-17  639 次阅读


腾讯云COS签名的实现

String tecentAuthorization(String method, String urlpath, Map header,
      String secretId, String secretKey, Map? urlParam) {
    int startTimestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
    int endTimestamp = startTimestamp + 86400;
    String keyTime = '$startTimestamp;$endTimestamp';

    String signKey = Hmac(sha1, utf8.encode(secretKey))
        .convert(utf8.encode(keyTime))
        .toString();
    String lowerMethod = method.toLowerCase();

    String urlParamList = '';
    String httpParameters = '';

    if (urlParam != null && urlParam.isNotEmpty) {
      Map uriEncodeUrlParam = {};
      urlParam.forEach((key, value) {
        uriEncodeUrlParam[Uri.encodeComponent(key).toLowerCase()] =
            Uri.encodeComponent(value);
      });

      List urlParamKeyList = uriEncodeUrlParam.keys.toList();
      urlParamKeyList.sort();

      for (var i = 0; i < urlParamKeyList.length; i++) {
        urlParamList = '${urlParamList + urlParamKeyList[i]};';
        httpParameters =
            '${httpParameters + urlParamKeyList[i]}=${uriEncodeUrlParam[urlParamKeyList[i]]}&';
      }
      if (httpParameters.isNotEmpty) {
        httpParameters = httpParameters.substring(0, httpParameters.length - 1);
      }
      if (urlParamList.isNotEmpty) {
        urlParamList = urlParamList.substring(0, urlParamList.length - 1);
      }
    }

    String headerList = '';
    String httpHeaders = '';
    Map uriEncodeHeader = {};
    header.forEach((key, value) {
      uriEncodeHeader[Uri.encodeComponent(key).toLowerCase()] =
          Uri.encodeComponent(value);
    });
    List headerKeyList = uriEncodeHeader.keys.toList();
    headerKeyList.sort();
    for (var i = 0; i < headerKeyList.length; i++) {
      headerList = '${headerList + headerKeyList[i]};';
      httpHeaders =
          '${httpHeaders + headerKeyList[i]}=${uriEncodeHeader[headerKeyList[i]]}&';
    }
    if (httpHeaders.isNotEmpty) {
      httpHeaders = httpHeaders.substring(0, httpHeaders.length - 1);
    }
    if (headerList.isNotEmpty) {
      headerList = headerList.substring(0, headerList.length - 1);
    }

    String httpString =
        '$lowerMethod\n$urlpath\n$httpParameters\n$httpHeaders\n';
    String stringtosign =
        'sha1\n$keyTime\n${sha1.convert(utf8.encode(httpString)).toString()}\n';

    String signature = Hmac(sha1, utf8.encode(signKey))
        .convert(utf8.encode(stringtosign))
        .toString();
    String authorization =
        'q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$keyTime&q-key-time=$keyTime&q-header-list=$headerList&q-url-param-list=$urlParamList&q-signature=$signature';
    return authorization;
  }

阿里云OSS签名的实现

getContentMd5(var variable) async {
    if (isString(variable)) {
      return base64.encode(md5.convert(utf8.encode(variable)).bytes);
    } else if (isFile(variable)) {
      List<int> bytes = await variable.readAsBytes();
      return base64.encode(md5.convert(bytes).bytes);
    } else {
      return "";
    }
  }

  getCanonicalizedOSSHeaders(Map headers) {
    Map<String, String> lowerHeaders = {};
    headers.forEach((key, value) {
      lowerHeaders[key.toLowerCase()] = value;
    });
    String canonicalizedOSSHeaders = "";
    List headerKeys = lowerHeaders.keys.toList();
    headerKeys.sort();
    for (var key in headerKeys) {
      if (key.startsWith("x-oss-")) {
        canonicalizedOSSHeaders += "$key:${lowerHeaders[key]}\n";
      }
    }
    return canonicalizedOSSHeaders;
  }

  Future<String> aliyunAuthorization(
      String method,
      String canonicalizedResource,
      Map headers,
      String contentMd5,
      String contentType) async {
    try {
      Map configMap = await getConfigMap();
      String accessKeyId = configMap['keyId'];
      String accessKeySecret = configMap['keySecret'];
      String gmtDate = HttpDate.format(DateTime.now());
      String uperCaseMethod = method.toUpperCase();
      String canonicalizedOSSHeaders = getCanonicalizedOSSHeaders(headers);
      String stringToSign =
          "$uperCaseMethod\n$contentMd5\n$contentType\n$gmtDate\n$canonicalizedOSSHeaders$canonicalizedResource";
      String signature = base64.encode(Hmac(sha1, utf8.encode(accessKeySecret))
          .convert(utf8.encode(stringToSign))
          .bytes);
      String authorization = "OSS $accessKeyId:$signature";
      return authorization;
    } catch (e) {
      FLog.error(
          className: 'AliyunManageAPI',
          methodName: 'aliyunAuthorization',
          text: formatErrorMessage({
            'method': method,
            'canonicalizedResource': canonicalizedResource,
            'headers': headers,
            'contentMd5': contentMd5,
            'contentType': contentType,
          }, e.toString()),
          dataLogType: DataLogType.ERRORS.toString());
      return "";
    }
  }