Подписание HTTP-запроса - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь подписать HTTP-запрос, используя Go, и у меня есть что-то вроде

const testSpecPublicKeyPEM = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
oYi+1hqp1fIekaxsyQIDAQAB
-----END PUBLIC KEY-----`

const testSpecPrivateKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
-----END RSA PRIVATE KEY-----`

func signPro(privateKey crypto.PrivateKey, pubKeyId string, r *http.Request, body []byte) error {
    prefs := []httpsig.Algorithm{httpsig.RSA_SHA256}
    headersToSign := []string{httpsig.RequestTarget, "date", "host", "content-length", "digest"}
    signer, _, err := httpsig.NewSigner(prefs, httpsig.DigestSha256, headersToSign, httpsig.Signature)
    if err != nil {
        return err
    }

    // If r were a http.ResponseWriter, call SignResponse instead.
    return signer.SignRequest(privateKey, pubKeyId, r, body)
}

_data := map[string]interface{} {
    "@context": []string{"https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"},
    "id": "http://localhost:10000/activity/7e88dfd5-51db-4c51-afbe-dfcdd24e8da8",
    "type": "Follow",
    "actor": "http://localhost:10000/test1",
    "object": "http://somefriend.local/test2",
    "instrument":  map[string]interface{}{
        "type": "Service",
        "name": "lala lele",
        "url": "http://localhost:10000",
    },
    "to": []string{"http://somefriend.local/test2"},
}

data, _ := json.Marshal(_data)
contentLength := strconv.Itoa(binary.Size(data))

privateKey, err := lib.ParseRsaPrivateKeyFromPemStr(testSpecPrivateKeyPEM)
if err != nil {
    log.Error("error getting private key")
    log.Error(err)
    app.JsonResponse(w, http.StatusInternalServerError, "")
    return
}

// we do this machinations for headers now
client := &http.Client{}
req, err := http.NewRequest("POST", "http://somefriend.local/profile/test2/inbox", bytes.NewReader(data))
if err != nil {
    log.Error(fmt.Sprintf("error creating request"))
    log.Error(err)
    app.JsonResponse(w, http.StatusInternalServerError, "")

    return
}

req.Header.Set("Content-Type", "application/activity+json")
req.Header.Set("Date", "2020-03-11 21:11:11")
req.Header.Set("Content-Length", contentLength)
req.Header.Set("Host", u.Host)

err = signPro(privateKey, "#main-key", req, data)
if err != nil {
    log.Error(fmt.Sprintf("error signing request"))
    log.Error(err)
    app.JsonResponse(w, http.StatusInternalServerError, "")

    return
}

В основном это должно добавить заголовки дайджеста и подписи к запросу, но другой конец возвращает недопустимую подпись при проверке.

У кого-нибудь есть пример, как правильно создать подпись HTTP-запроса с Go и что он подчиняется https://tools.ietf.org/html/draft-cavage-http-signatures-12?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...