获取授权令牌
概述
该方法允许使用从 RuStore 控制台系统中获取的私钥来生成 JWE 令牌。 此外,该方法还会检查应用所有者的活跃状态。
提示
为了成功执行请求,请先生成私钥。
交互参数
POST
https://public-api.rustore.ru/public/auth/
| 属性 | 类型 | 是否必填 | 位置 | 描述 | 示例 |
|---|---|---|---|---|---|
̶c̶o̶m̶p̶a̶n̶y̶I̶d̶已弃用 | ̶s̶t̶r̶i̶n̶g̶ | ̶是̶,̶如̶果̶未̶指̶定̶ ̶k̶e̶y̶I̶d̶ | ̶b̶o̶d̶y̶ | ̶公̶司̶的 ̶i̶d̶̶ | ̶1̶2̶3̶ |
keyId | string | 是 | body | 密钥的 id | |
timestamp | string | 是 | body | 请求发送时间。 与当前服务器时间的偏差不得超过 60 秒。 | 2022-07-08T13:24:41.8328711+03:00 |
signature | string | 是 | body | 包含请求 timestamp 字符串的 SHA-512 哈希值的 RSA 签名。 签名创建和验证算法:SHA512withRSA。 生成 signature 的必要步骤: 1. 通过将密钥标识符 keyId 和当前日期 timestamp 拼接,创建待签名消息。示例: • keyId: 123• timestamp: 2024-06-18T11:49:08.290+03:00• 生成的消息(拼接结果): 1232024-06-18T11:49:08.290+03:002. 使用 SHA-512 算法计算步骤 1 中消息的哈希值,得到 9d864a0…………3d757f。3. 对在 RuStore 控制台中获取的 Base64 格式私钥进行解码,以获得 RSA 私钥。 使用该私钥为步骤 2 中的哈希值创建数字签名。4. 将步骤 3 中的签名编码为 Base64 以获取 signature,最终结果 AkLM0pQM……….xw== 即为 signature 参数。 | N/A |
获取授权令牌示例
- Python
- Java
import sys
import base64
import datetime
import json
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA512
def generate_signature(key_id, private_key_content):
private_key = RSA.import_key(base64.b64decode(private_key_content))
timestamp = datetime.datetime.now(datetime.timezone.utc).isoformat(timespec='milliseconds')
message_to_sign = key_id + timestamp
print("Message to sign:", message_to_sign)
hash_obj = SHA512.new(message_to_sign.encode())
signer = pkcs1_15.new(private_key)
signature_bytes = signer.sign(hash_obj)
signature_value = base64.b64encode(signature_bytes).decode()
return json.dumps({
"keyId": key_id,
"timestamp": timestamp,
"signature": signature_value
}, indent=2)
def main():
if len(sys.argv) < 3:
print("Обязательные параметры: keyId - id ключа, privateKey - приватный ключ\nПример: python ruStoreTokenGenerator.py 354751 MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClnpt+5Ndcz/GBz5cXL0Z5u/nowqXWv+KwyQijSLClgar/r1jy2bnTAnvBssTOqQN...")
else:
key_id = sys.argv[1]
private_key_content = sys.argv[2]
print(generate_signature(key_id, private_key_content))
if __name__ == "__main__":
main()
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
public class SignatureGenerator {
public static void main(String[] args) throws NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException {
if (args.length < 2) {
System.out.print("Обязательные параметры: keyId - id ключа, privateKey - приватный ключ\nПример: ruStoreTokenGenerator.jar 354751 MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClnpt+5Ndcz/GBz5cXL0Z5u/nowqXWv+KwyQijSLClgar/r1jy2bnTAnvBssTOqQN...");
} else {
System.out.println(generateSignature(args[0], args[1]));
}
}
private static String generateSignature(String keyId, String privateKeyContent) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
PrivateKey privateKey = kf.generatePrivate(keySpecPKCS8);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
String timestamp = dateFormat.format(new Date());
String messageToSign = keyId.concat(timestamp);
System.out.println("Message to sign: " + messageToSign);
Signature signature = Signature.getInstance("SHA512withRSA");
signature.initSign(privateKey);
signature.update(messageToSign.getBytes());
byte[] signatureBytes = signature.sign();
String signatureValue = Base64.getEncoder().encodeToString(signatureBytes);
return String.format("{\n \"keyId\":\"%s\",\n \"timestamp\":\"%s\",\n \"signature\":\"%s\"\n}\n", keyId, timestamp, signatureValue);
}
}
如果您在理解 signature 参数的生成算法时遇到问题,请使用 .jar 文件来生成该参数。
请传递密钥 ID 和获取到的私钥。 作为响应,您将获得一个用于 POST /public/auth/ 请求的请求体,其中包含 keyId、timestamp 和 signature 参数。
提示
生成的 signature 参数有效期为 1 分钟,因为它直接依赖于 timestamp。
响应参数
| 属性 | 类型 | 是否必填 | 描述 | 示例 |
|---|---|---|---|---|
code | string | 是 | 响应代码。 | error/OK |
message | string | 否 | 响应代码的详细说明(在出错时)。 | Range timestamp not valid |
body{} | object | 是 | N/A | N/A |
timestamp | timestamptz | 是 | 响应时间。 | 2022-07-08T13:24:41.8328711+03:00 |
body{}
| 属性 | 类型 | 是否必填 | 描述 | 示例 |
|---|---|---|---|---|
jwe | string | 是 | RuStore API 的访问令牌(payload 内容见下文)。 可重复使用。 | eyJjdHkiOiJK…sv16aBl8tTg.VkWuTw |
ttl | number | 是 | 令牌的有效期(以秒为单位)。 有效期为 900 秒。 | 900 |
可能的错误
code | message | 描述 | 可能的操作 |
|---|---|---|---|
400 | Range timestamp not valid | timestamp 参数偏差超过 60 秒。 | 更新 timestamp 和 signature |
400 | Signature encode error | signature 参数生成不正确 | 需要重新生成 signature 参数。 |
400 | KeyId must not be null, please use this parameter for token generation | 必须使用 keyId 参数之一。 | 请检查是否指定了 keyId 参数。 |
请求示例
curl --location 'https://public-api.rustore.ru/public/auth' \
--header 'Content-Type: application/json' \
--data '{
"keyId":"1275328",
"timestamp":"2023-08-11T13:31:17.580+03:00",
"signature":"U4kh.......nFkbuw=="
}
成功响应示例
{
"code": "OK",
"message": null,
"body": {
"jwe": "eyJlbmMiOiJBM......nuuM227D_O1A",
"ttl": 900
},
"timestamp": "2023-08-11T13:31:17.580+03:00"
}