Closed Shark-vil closed 3 years ago
Please refer to the API specification (unfortunately it's in Chinese, but Google Translate should work).
If you can't get other players' skins displayed in the game, please turn on -Dauthlibinjector.debug
option and upload the MC client console log.
Please refer to the API specification (unfortunately it's in Chinese, but Google Translate should work).
If you can't get other players' skins displayed in the game, please turn on
-Dauthlibinjector.debug
option and upload the MC client console log.
I found the reason. For himself, the client requests a skin with the parameter "unsigned=true". But for other players, a similar request is sent with the "unsigned=false" parameter. After that I get the message:
Signature is missing from textures payload
Is it possible to always use a parameter in the false state? I don't quite understand how signatures work, I can't find good documentation on how to create them and how to associate them with textures. Therefore, I would like to always ignore this parameter.
Please refer to the API specification (unfortunately it's in Chinese, but Google Translate should work). If you can't get other players' skins displayed in the game, please turn on
-Dauthlibinjector.debug
option and upload the MC client console log.I found the reason. For himself, the client requests a skin with the parameter "unsigned=true". But for other players, a similar request is sent with the "unsigned=false" parameter. After that I get the message:
Signature is missing from textures payload
Is it possible to always use a parameter in the false state? I don't quite understand how signatures work, I can't find good documentation on how to create them and how to associate them with textures. Therefore, I would like to always ignore this parameter.
Currently, there is no way to disable the signature.
But the document is here (I think Google Translate will work on this part of document): https://github.com/yushijinhun/authlib-injector/wiki/Yggdrasil-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83#%E8%A7%92%E8%89%B2%E4%BF%A1%E6%81%AF%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96
I can also paste my implementation code here later if you need.
Please refer to the API specification (unfortunately it's in Chinese, but Google Translate should work). If you can't get other players' skins displayed in the game, please turn on
-Dauthlibinjector.debug
option and upload the MC client console log.I found the reason. For himself, the client requests a skin with the parameter "unsigned=true". But for other players, a similar request is sent with the "unsigned=false" parameter. After that I get the message:
Signature is missing from textures payload
Is it possible to always use a parameter in the false state? I don't quite understand how signatures work, I can't find good documentation on how to create them and how to associate them with textures. Therefore, I would like to always ignore this parameter.
Currently, there is no way to disable the signature.
But the document is here (I think Google Translate will work on this part of document): https://github.com/yushijinhun/authlib-injector/wiki/Yggdrasil-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83#%E8%A7%92%E8%89%B2%E4%BF%A1%E6%81%AF%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96
I can also paste my implementation code here later if you need.
It would be nice if you can attach an example. I tried to do everything according to the available documentation, but to no avail. Here's what I did:
$properties_textures_value = json_encode([
'timestamp' => strtotime('now'),
'profileId' => $profile_id,
'profileName' => $user->name,
'signatureRequired' => !$unsigned,
'textures' => $textures,
]);
$properties_textures_value_base64 = base64_encode($properties_textures_value); $private_key = $this->get_private_key();
if (!$unsigned) { openssl_sign($properties_textures_value_base64, $signature, $private_key); $signature_base64 = base64_encode($signature); array_push($properties, [ 'name' => 'textures', 'value' => $properties_textures_value_base64, 'signature' => $signature_base64, ]); } else { array_push($properties, [ 'name' => 'textures', 'value' => $properties_textures_value_base64 ]); }
return response()->json([ 'id' => $profile_id, 'name' => $user->name, 'properties' => $properties ], 200);
I get a result like this:
https://mc.pipbuck.ru/api/authserver/sessionserver/session/minecraft/profile/338da3b48cf74a438de8755026535a6d
But now he writes to me that:
"Textures payload has been tampered with (signature invalid)"
I have no idea what I'm doing wrong. I understand that this problem is not related to your development, and are solely my misunderstanding of the system. But I hope you will help to understand in which direction you need to move.
The documentation is not very clear and needs to be improved. Here are some examples of implementing texture signature:
Here is my implementation, which is in Laravel's ORM model, FYR
class Profile extends Model
{
protected $connection = 'default';
protected $table = 'profile';
/**
* @return array
*/
public function getSerialization($properties = false, $unsigned = true)
{
$arr = [
'id' => $this->uuid,
'name' => $this->name
];
if ($properties) {
$textures = array();
// steve
if ($this->skin_default != null) {
$url = Config::get('base_url') . "/textures/$this->skin_default";
$textures['SKIN'] = array(
'url' => $url,
'metadata' => array(
'model' => 'default'
)
);
}
// alex
if ($this->skin_slim != null) {
$url = Config::get('base_url') . "/textures/$this->skin_slim";
$textures['SKIN'] = array(
'url' => $url,
'metadata' => array(
'model' => 'slim'
)
);
}
// cape
if ($this->cape != null) {
$url = Config::get('base_url') . "/textures/$this->cape";
$textures['CAPE'] = array(
'url' => $url
);
}
$value = array(
'timestamp' => time() * 1000,
'profileId' => $this->uuid,
'profileName' => $this->name,
'textures' => $textures,
'signatureRequired' => !$unsigned
);
$value = base64_encode(json_encode($value, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK));
$properties = array(
array(
'name' => 'textures',
'value' => $value
)
);
if (!$unsigned) {
foreach ($properties as $i => $p) {
$key = openssl_pkey_get_private(Config::get('yggdrasil_private_key'));
if (!$key) throw new \Exception("Can not parse private key.");
openssl_sign($p['value'], $s, $key);
$properties[$i]['signature'] = base64_encode($s);
}
}
$arr['properties'] = $properties;
}
return $arr;
}
}
Well, I seem to have almost achieved what I wanted, but I have another question.
The documentation says that I have to output the public key from the main api (index) link. By default, however, the key is displayed with "\r\n, \n" hyphenation characters. Should I get rid of them as shown in the screenshot or not? Or does this string also need to be converted to base64 format?
Okay, I checked this output with "openssl_verify", and it looks like I should leave it, java decodes everything by itself.
That's it, it works! Thank you so much for your help! 😊
I wanted to implement my own authentication server and made the main API routes.
All links work as expected. However, the last link only works for the client. As I understand it, using this link you cannot get skins of other players during the game. Could you tell me in which direction I need to study the API in order to load skins of other players for the client?