基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
基于公钥加密的认证
更新时间:2026-04-10 11:58:36
当您将 HTTP 请求发送到 OBShell 时,OBShell 需要对您的请求进行身份认证,以便识别请求者身份和保护传输过程数据安全性防止重复攻击。
使用说明
步骤一:密文生成。
- 调用
/api/v1/secret接口获得目标 agent 的公钥 - 生成一个 JSON 字符串:{ "password": ${明文密码}, "ts": ${过期时间戳} }
- 使用 RSA 算法,结合上面得到的公钥,对 JSON 字符串加密,得到字节序列 b
- 对 b 进行 base64 编码,得到密文
- 调用
步骤二:使用密文构造认证信息并发送 HTTP 请求。 您将 HTTP 请求发送至 obshell 时,需保证 HTTP Header 中包含 X-OCS-Auth 字段,以便 obshell 服务端对请求进行认证。
X-OCS-Auth:{密文} 。
OBShell 服务端在接受到您的请求后,会解析出sys租户的root用户的密码,并加以校验。如果校验通过,则继续处理请求,否则将报错。目前仅支持 HTTP Header 中包含认证字符串。
Python 生成示例代码
import requests as req
import json
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
import base64
import time
def encrypt(s, pk):
key = RSA.import_key(base64.b64decode(pk))
cipher = PKCS1_cipher.new(key)
return base64.b64encode(cipher.encrypt(bytes(s.encode('utf8')))).decode('utf8')
def auth(pwd, pk):
auth_json = json.dumps({'password': pwd, 'ts': int(time.time()) + 5})
return encrypt(auth_json, pk)
resp = req.get('http://xxx.xxx.1:2886/api/v1/secret').text
resp = json.loads(resp)
pk = resp['data']['public_key']
pwd = '1111'
print(auth(pwd, pk))
golang 生成示例代码
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
// RSAEncrypt function encrypts a byte array using the provided public key
func RSAEncrypt(raw []byte, pk string) (string, error) {
pkix, err := base64.StdEncoding.DecodeString(pk)
if err != nil {
return "", err
}
pub, err := x509.ParsePKCS1PublicKey(pkix)
if err != nil {
return "", err
}
b, err := rsa.EncryptPKCS1v15(rand.Reader, pub, raw)
return base64.StdEncoding.EncodeToString(b), err
}
// getPublicKey function retrieves the public key from the API
func getPublicKey(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
var response struct {
Data struct {
PublicKey string `json:"public_key"`
} `json:"data"`
}
if err = json.Unmarshal(body, &response); err != nil {
return "", err
}
return response.Data.PublicKey, nil
}
// auth function creates an authentication JSON object and encrypts it
func auth(pwd string, pk string) (string, error) {
authMap := map[string]interface{}{
"password": pwd,
"ts": time.Now().Unix() + 5,
}
authJSON, err := json.Marshal(authMap)
if err != nil {
return "", err
}
return RSAEncrypt(authJSON, pk)
}
func genAuth() (err error) {
publicKey, err := getPublicKey("http://xxx.xxx.1:2886/api/v1/secret")
if err != nil {
return
}
// Authenticate using the password and public key
encryptedAuth, err := auth("1111", publicKey)
if err != nil {
return
}
fmt.Println(encryptedAuth)
return nil
}
func main() {
if err := genAuth(); err != nil {
fmt.Println("err: ", err)
}
}
java 生成示例代码
package com.oceanbase.vos
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.crypto.Cipher;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class Main {
public static void main(String[] args) {
try {
// 获取公钥
String pkcs1PublicKeyStr = getPublicKey("http://xxx.xxx.1:2886/api/v1/secret");
String password = "1111";
long timestamp = System.currentTimeMillis() / 1000 + 100000;
PublicKey publicKey = convertPKCS1ToPublicKey(pkcs1PublicKeyStr);
String encryptedPassword = encryptPasswordWithRSA(password, timestamp, publicKey);
System.out.println(encryptedPassword);
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getPublicKey(String urlStr) throws Exception {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
JSONObject jsonResponse = JSON.parseObject(response.toString());
return jsonResponse.getJSONObject("data").getString("public_key");
}
} else {
throw new Exception("HTTP request failed with code " + responseCode);
}
}
private static PublicKey convertPKCS1ToPublicKey(String pkcs1PublicKeyStr) throws Exception {
pkcs1PublicKeyStr = pkcs1PublicKeyStr.replaceAll("\\n", "")
.replace("-----BEGIN RSA PUBLIC KEY-----", "")
.replace("-----END RSA PUBLIC KEY-----", "");
byte[] pkcs1PublicKey = Base64.getDecoder().decode(pkcs1PublicKeyStr);
ASN1InputStream asn1InputStream = new ASN1InputStream(pkcs1PublicKey);
ASN1Sequence sequence = (ASN1Sequence) asn1InputStream.readObject();
BigInteger modulus = ((ASN1Integer) sequence.getObjectAt(0)).getValue();
BigInteger publicExponent = ((ASN1Integer) sequence.getObjectAt(1)).getValue();
asn1InputStream.close();
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(publicKeySpec);
}
private static String encryptPasswordWithRSA(String password, long timestamp, PublicKey publicKey) throws Exception {
JSONObject json = new JSONObject();
json.put("password", password);
json.put("ts", timestamp);
String jsonString = json.toString();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(jsonString.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
}