検索
ホームページバックエンド開発PHPチュートリアルPHP、Java、および C# は、アプリケーションと REST サーバー間の安全な通信を確保し、秘密キーの盗難やデータ改ざんなどの悪意のある攻撃を防止するために、URI パラメーター署名アルゴリズムを実装しています。

PHP、Java、および C# は、アプリケーションと REST サーバー間の安全な通信を確保し、秘密キーの盗難やデータ改ざんなどの悪意のある攻撃を防ぐための URI パラメーター署名アルゴリズムを実装しています

はじめに

アプリケーションが HTTP POST または HTTP GET リクエストに基づいて Open API 呼び出しリクエストを送信するとき、アプリケーションと REST サーバー間の安全な通信を確保し、秘密キーの盗難やデータの改ざんなどの悪意のある攻撃を防ぐために、REST サーバーはパラメータ署名メカニズムを使用します。アプリケーションは Open API を呼び出す前に、すべてのリクエスト パラメータの MD5 署名を計算し、それをリクエスト パラメータに追加する必要があります。パラメータ名は「sign」です。 REST サーバーはリクエストを受信すると、署名を再計算し、その値がアプリケーションによって渡された署名パラメーター値と一致しているかどうかを判断して、現在の Open API 呼び出しリクエストが第三者によって偽造または改ざんされていないかどうかを判断します。

Open API を呼び出す前に、アプリケーションは OAuth2.0 サービスを通じてユーザーまたはプラットフォームから認可を取得する必要があります。認可を取得した後、次の 3 つの重要なパラメーターを取得します。

  • access_token: https に基づく Open API を呼び出すときに必要なアクセス許可コード;
  • session_key: 呼び出し時に必要なアクセス許可http コードに基づくオープン API;
  • session_secret: http に基づいてオープン API を呼び出すときにパラメーターの署名を計算するために使用される署名キー。

このうち、session_secret パラメータはパラメータの署名に必要な署名鍵です。これは、Facebook や Renren などのプラットフォームとは少し異なります。通常、これら 2 つのプラットフォームはパラメーター署名を行うときに 2 つの署名キーを使用します。

  • Open API がアプリケーション サーバー経由で呼び出される場合、アプリケーションの登録時に取得されるアプリケーション キー (つまり API キー) はパラメータ署名キーです。
  • Open API が JavaScript 経由で呼び出される場合は、または ActionScript クライアント言語が Open API を呼び出す場合、アプリケーションがユーザー認証を取得した後に取得されるセッション シークレットがパラメーターの署名キーになります。もちろん、サーバー経由で Open API を呼び出すときに、Session Secret を署名キーとして使用することもできます。

署名アルゴリズム

パラメーター署名の計算に参加するリクエスト パラメーターがそれぞれ "k1"、"k2"、および "k3" であると仮定します。値はそれぞれ「v1」、「v2」、「v3」です。パラメータ署名の計算方法は次のとおりです。

  • リクエストパラメータを「key=value」形式、つまり, "k1=v1", "k2 =v2", "k3=v3";
  • 書式設定されたパラメーターのキーと値のペアを辞書の昇順に並べて結合します。つまり、「k1=v1k2=」 v2k3=v3";
  • アプリケーションが OAuth2.0 プロトコルを通じてアクセス トークンを取得するときに取得した session_secret パラメーターの値を、結合された文字列の末尾に追加します。
  • の MD5 値上記の文字列は署名の値です。

注: この時点では符号パラメータの値がまだ不明であり、計算する必要があるため、署名を計算するときにリクエスト パラメータに符号パラメータを含めないでください

また、署名の計算時にはパラメータをurlencoded(「application/x-www-form-urlencoded」エンコード)する必要はありませんが、リクエスト送信時にはurlencoded処理が必要となります。多くの開発者にとって、間違いを犯しやすい最も一般的な問題です。

署名プロセスの例

アプリケーションが uid 67411167 のユーザーの基本情報を取得する必要があり、アプリケーションが OAuth2 を通じてアクセス トークンを取得する前のプロセスにあるとします。 0 サービス 取得された session_key および session_secret パラメーターの値は次のとおりです:

  • session_key: "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR 1A="
  • session_secret: "27e1be4fdcaa83d7f61c489994ff6ed6"

Open API を呼び出すときのシステム時刻 (PHP では、date('Y-m-d H:i: s')) は「2011-06-21 17:18:09」です。REST サーバーが呼び出し結果を JSON 形式で返すことを期待します。つまり、パラメーター署名の計算に参加するリクエスト パラメーターのセットは次のとおりです。 >

<span style="color: #000000;">[    </span>"session_key" => "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A="<span style="color: #000000;">,    </span>"timestamp" => "2011-06-21 17:18:09"<span style="color: #000000;">,    </span>"format" => "json"<span style="color: #000000;">,    </span>"uid" => 67411167<span style="color: #000000;">]</span>
 
署名を計算する具体的なプロセスは次のとおりです:

    リクエスト パラメーターを「key=value」にフォーマットします。
<span style="color: #000000;"> [    </span>"session_key=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A="<span style="color: #000000;">,    </span>"timestamp=2011-06-21 17:18:09"<span style="color: #000000;">,    </span>"format=json"<span style="color: #000000;">,    </span>"uid=67411167"<span style="color: #000000;"> ]</span>
 
    フォーマットされたパラメータのキーと値のペアを辞書の昇順に並べると、次のようになります。パラメータセット:
<span style="color: #000000;"> [    </span>"format=json"<span style="color: #000000;">,    </span>"session_key=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A="<span style="color: #000000;">,    </span>"timestamp=2011-06-21 17:18:09"<span style="color: #000000;">,    </span>"uid=67411167"<span style="color: #000000;"> ]</span>
 
  • 将前面排序好的参数集拼接在一起,得到如下字符串:
format<span style="color: #339933;">=</span>jsonsession_key<span style="color: #339933;">=</span>9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A<span style="color: #339933;">=</span>timestamp<span style="color: #339933;">=</span><span style="color: #cc66cc;">2011</span><span style="color: #339933;">-</span><span style="color: #208080;">06</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #cc66cc;">17</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">18</span><span style="color: #339933;">:</span>09uid<span style="color: #339933;">=</span><span style="color: #cc66cc;">67411167</span>
  • 在拼接好的字符串末尾追加上应用通过OAuth2.0协议获取Access Token时所获取到的session_secret参数值,得到如下字符串:
format<span style="color: #339933;">=</span>jsonsession_key<span style="color: #339933;">=</span>9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A<span style="color: #339933;">=</span>timestamp<span style="color: #339933;">=</span><span style="color: #cc66cc;">2011</span><span style="color: #339933;">-</span><span style="color: #208080;">06</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">21</span> <span style="color: #cc66cc;">17</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">18</span><span style="color: #339933;">:</span>09uid<span style="color: #339933;">=</span>6741116727e1be4fdcaa83d7f61c489994ff6ed6
  • 对前面得到的字符串求MD5签名,得到的d24dd357a95a2579c410b3a92495f009就是调用API时所需要的sign参数值。

接下来便可以通过HTTP POST方法或HTTP GET方法请求Open API的REST服务器,进行接口调用了,如:

GET /rest/2.0/passport/users/getInfo?session_key=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A%3D&timestamp=2011-06-21+17%3A18%3A09&format=json&uid=67411167&sign=d24dd357a95a2579c410b3a92495f009 HTTP/1.1<span style="color: #000000;">Host: openapi.baidu.comUser</span>-<span style="color: #000000;">Agent: Client of Baidu Open PlatformAccept: </span>*<span style="color: #008000;">/*</span><span style="color: #008000;">Accept-Encoding: gzip,deflateAccept-Charset: utf-8Connection: close或POST /rest/2.0/passport/users/getInfo HTTP/1.1Host: openapi.baidu.comUser-Agent: Client of Baidu Open PlatformAccept: </span><span style="color: #008000;">*/</span>*<span style="color: #000000;">Accept</span>-<span style="color: #000000;">Encoding: gzip,deflateAccept</span>-Charset: utf-8<span style="color: #000000;">Content</span>-Length: 179<span style="color: #000000;">Connection: close session_key</span>=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A%3D&timestamp=2011-06-21+17%3A18%3A09&format=json&uid=67411167&sign=d24dd357a95a2579c410b3a92495f009

 

签名算法实现代码

PHP代码实现

获取签名的PHP代码实现方式如下所示:

<span style="color: #008000;">/*</span><span style="color: #008000;">*  * 签名生成算法  * @param  array  $params API调用的请求参数集合的关联数组,不包含sign参数  * @param  string $secret 签名的密钥即获取access token时返回的session secret  * @return string 返回参数签名值  </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">function</span> getSignature(<span style="color: #800080;">$params</span>, <span style="color: #800080;">$secret</span><span style="color: #000000;">) {    </span><span style="color: #800080;">$str</span> = '';  <span style="color: #008000;">//</span><span style="color: #008000;">待签名字符串    //先将参数以其参数名的字典序升序进行排序</span>    <span style="color: #008080;">ksort</span>(<span style="color: #800080;">$params</span><span style="color: #000000;">);    </span><span style="color: #008000;">//</span><span style="color: #008000;">遍历排序后的参数数组中的每一个key/value对</span>    <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$params</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$k</span> => <span style="color: #800080;">$v</span><span style="color: #000000;">) {        </span><span style="color: #008000;">//</span><span style="color: #008000;">为key/value对生成一个key=value格式的字符串,并拼接到待签名字符串后面</span>        <span style="color: #800080;">$str</span> .= "<span style="color: #800080;">$k</span>=<span style="color: #800080;">$v</span>"<span style="color: #000000;">;    }    </span><span style="color: #008000;">//</span><span style="color: #008000;">将签名密钥拼接到签名字符串最后面</span>    <span style="color: #800080;">$str</span> .= <span style="color: #800080;">$secret</span><span style="color: #000000;">;    </span><span style="color: #008000;">//</span><span style="color: #008000;">通过md5算法为签名字符串生成一个md5签名,该签名就是我们要追加的sign参数值</span>    <span style="color: #0000ff;">return</span> <span style="color: #008080;">md5</span>(<span style="color: #800080;">$str</span><span style="color: #000000;">); }</span>

 

调用示例:

<span style="color: #800080;">$uid</span> = 67411167<span style="color: #000000;">;</span><span style="color: #800080;">$params</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(    </span>"session_key" => "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",    "timestamp" => "2011-06-21 17:18:09",    "format" => "json",    "uid" => <span style="color: #800080;">$uid</span>,<span style="color: #000000;">);</span><span style="color: #800080;">$sign</span> = getSignature(<span style="color: #800080;">$params</span>, "27e1be4fdcaa83d7f61c489994ff6ed6");
 

Java代码实现

获取签名的java代码实现方式如下所示:

<span style="color: #008000;">/**</span><span style="color: #008000;"> * 签名生成算法 * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> HashMap<string> params 请求参数集,所有参数必须已转换为字符串类型 * </string></span><span style="color: #808080;">@param</span><span style="color: #008000;"> String secret 签名密钥 * </span><span style="color: #808080;">@return</span><span style="color: #008000;"> 签名 * </span><span style="color: #808080;">@throws</span><span style="color: #008000;"> IOException </span><span style="color: #008000;">*/</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> String getSignature(HashMap<string> params, String secret) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> IOException{    </span><span style="color: #008000;">//</span><span style="color: #008000;"> 先将参数以其参数名的字典序升序进行排序</span>    Map<string string> sortedParams = <span style="color: #0000ff;">new</span> TreeMap<string string><span style="color: #000000;">(params);    Set</span><entry string>> entrys =<span style="color: #000000;"> sortedParams.entrySet();     </span><span style="color: #008000;">//</span><span style="color: #008000;"> 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起</span>    StringBuilder basestring = <span style="color: #0000ff;">new</span><span style="color: #000000;"> StringBuilder();    </span><span style="color: #0000ff;">for</span> (Entry<string string><span style="color: #000000;"> param : entrys) {        basestring.append(param.getKey()).append(</span>"="<span style="color: #000000;">).append(param.getValue());    }    basestring.append(secret);     </span><span style="color: #008000;">//</span><span style="color: #008000;"> 使用MD5对待签名串求签</span>    <span style="color: #0000ff;">byte</span>[] bytes = <span style="color: #0000ff;">null</span><span style="color: #000000;">;    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {        MessageDigest md5 </span>= MessageDigest.getInstance("MD5"<span style="color: #000000;">);        bytes </span>= md5.digest(basestring.toString().getBytes("UTF-8"<span style="color: #000000;">));    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (GeneralSecurityException ex) {        </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> IOException(ex);    }     </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将MD5输出的二进制结果转换为小写的十六进制</span>    StringBuilder sign = <span style="color: #0000ff;">new</span><span style="color: #000000;"> StringBuilder();    </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i ) {        String hex = Integer.toHexString(bytes[i] & 0xFF<span style="color: #000000;">);        </span><span style="color: #0000ff;">if</span> (hex.length() == 1<span style="color: #000000;">) {            sign.append(</span>"0"<span style="color: #000000;">);        }        sign.append(hex);    }    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> sign.toString();}</span></string></entry></string></string></string>

 

注意:计算签名时所有参数的key和value都必须先转换为对应的字符串类型,因为在HTTP请求中传递的内容都是字符串类型的,很多开发者都因为没注意到这点,直接将非字符串类型的参数的二进制值传递了进去,结果导致签名与服务端计算的不一致而出错。

C#代码实现

获取签名的C#代码实现方式如下所示:

<span style="color: #808080;">///</span> <span style="color: #808080;"><summary></summary></span><span style="color: #808080;">///</span><span style="color: #008000;"> 计算参数签名</span><span style="color: #808080;">///</span> <span style="color: #808080;"></span><span style="color: #808080;">///</span> <span style="color: #808080;"><param name="params"></span><span style="color: #008000;">请求参数集,所有参数必须已转换为字符串类型</span><span style="color: #808080;"></span><span style="color: #808080;">///</span> <span style="color: #808080;"><param name="secret"></span><span style="color: #008000;">签名密钥</span><span style="color: #808080;"></span><span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span><span style="color: #008000;">签名</span><span style="color: #808080;"></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">string</span> getSignature(IDictionarystring, <span style="color: #0000ff;">string</span>> parameters, <span style="color: #0000ff;">string</span><span style="color: #000000;"> secret){    </span><span style="color: #008000;">//</span><span style="color: #008000;"> 先将参数以其参数名的字典序升序进行排序</span>    IDictionarystring, <span style="color: #0000ff;">string</span>> sortedParams = <span style="color: #0000ff;">new</span> SortedDictionarystring, <span style="color: #0000ff;">string</span>><span style="color: #000000;">(parameters);    IEnumerator</span><keyvaluepair style="color: #0000ff;">string, <span style="color: #0000ff;">string</span>>> iterator=<span style="color: #000000;"> sortedParams.GetEnumerator();     </span><span style="color: #008000;">//</span><span style="color: #008000;"> 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起</span>    StringBuilder basestring= <span style="color: #0000ff;">new</span><span style="color: #000000;"> StringBuilder();    </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (iterator.MoveNext()) {            </span><span style="color: #0000ff;">string</span> key =<span style="color: #000000;"> iterator.Current.Key;            </span><span style="color: #0000ff;">string</span> value =<span style="color: #000000;"> iterator.Current.Value;            </span><span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">string</span>.IsNullOrEmpty(key) && !<span style="color: #0000ff;">string</span><span style="color: #000000;">.IsNullOrEmpty(value)){                basestring.Append(key).Append(</span><span style="color: #800000;">"</span><span style="color: #800000;">=</span><span style="color: #800000;">"</span><span style="color: #000000;">).Append(value);            }    }    basestring.Append(secret);     </span><span style="color: #008000;">//</span><span style="color: #008000;"> 使用MD5对待签名串求签</span>    MD5 md5 =<span style="color: #000000;"> MD5.Create();    </span><span style="color: #0000ff;">byte</span>[] bytes =<span style="color: #000000;"> md5.ComputeHash(Encoding.UTF8.GetBytes(basestring.ToString()));     </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将MD5输出的二进制结果转换为小写的十六进制</span>    StringBuilder result = <span style="color: #0000ff;">new</span><span style="color: #000000;"> StringBuilder();    </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i ) {            <span style="color: #0000ff;">string</span> hex = bytes[i].ToString(<span style="color: #800000;">"</span><span style="color: #800000;">x</span><span style="color: #800000;">"</span><span style="color: #000000;">);            </span><span style="color: #0000ff;">if</span> (hex.Length == <span style="color: #800080;">1</span><span style="color: #000000;">) {                result.Append(</span><span style="color: #800000;">"</span><span style="color: #800000;">0</span><span style="color: #800000;">"</span><span style="color: #000000;">);            }            result.Append(hex);    }     </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> result.ToString();}</span></keyvaluepair>

 服务器接受请求后,同样对参数进行签名,如果签名相同则数据没有被修改或者丢失。

注意:计算签名时所有参数的key和value都必须先转换为对应的字符串类型,因为在HTTP请求中传递的内容都是字符串类型的,很多开发者都因为没注意到这点,直接将非字符串类型的参数的二进制值传递了进去,结果导致签名与服务端计算的不一致而出错。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPで__CLONEメソッドを使用する方法は?PHPで__CLONEメソッドを使用する方法は?May 15, 2025 pm 08:48 PM

PHPの__Cloneメソッドは、オブジェクトクローン時にカスタム操作を実行するために使用されます。クローンキーワードを使用してオブジェクトをクローニングする場合、オブジェクトに__クローンメソッドがある場合、メソッドが自動的に呼び出され、クローン型属性をリセットしてクローンオブジェクトの独立性を確保するなど、クローンプロセス中にカスタマイズされた処理を許可します。

PHPでGOTOステートメントを使用する方法は?PHPでGOTOステートメントを使用する方法は?May 15, 2025 pm 08:45 PM

PHPでは、GOTOステートメントは、プログラムの特定のタグに無条件にジャンプするために使用されます。 1)複雑なネストされたループまたは条件付きステートメントの処理を簡素化することができますが、2)GOTOを使用すると、コードの理解と維持が困難になる場合があります。3)構造化された制御ステートメントの使用を優先することをお勧めします。全体として、gotoは注意して使用する必要があり、コードの読みやすさと保守性を確保するために、ベストプラクティスに従う必要があります。

PHPにデータ統計を実装する方法は?PHPにデータ統計を実装する方法は?May 15, 2025 pm 08:42 PM

PHPでは、組み込み関数、カスタム関数、およびサードパーティライブラリを使用してデータ統計を実現できます。 1)array_sum()やcount()などの組み込み関数を使用して、基本統計を実行します。 2)カスタム関数を記述して、中央値などの複雑な統計を計算します。 3)PHP-MLライブラリを使用して、高度な統計分析を実行します。これらの方法により、データ統計を効率的に実行できます。

PHPで匿名関数を使用する方法は?PHPで匿名関数を使用する方法は?May 15, 2025 pm 08:39 PM

はい、PHPの匿名関数は、名前のない関数を参照します。これらは、他の関数へのパラメーターとして、および関数の返品値として渡すことができ、コードをより柔軟で効率的にします。匿名関数を使用する場合、範囲とパフォーマンスの問題に注意を払う必要があります。

PHPでarray_randでキーをランダムに取得するにはどうすればよいですか?PHPでarray_randでキーをランダムに取得するにはどうすればよいですか?May 15, 2025 pm 08:36 PM

PHPでは、array_rand関数を使用して、配列からランダムにキーを取得できます。 1)array_rand($ array)を使用して、単一のランダムキーを取得します。 2)array_rand($ array、n)を使用して、nランダムキーを取得します。この機能は効率的で柔軟ですが、大規模なデータの主要なカウントとパフォーマンスの問題の制限に注意を払う必要があります。

PHPで機能のホットアップデートを実装する方法は?PHPで機能のホットアップデートを実装する方法は?May 15, 2025 pm 08:33 PM

PHPに機能のホットアップデートを実装するには、次の3つの方法があります。 2。opcacheを使用して、opcacheを再起動してホットアップデートを実現します。 3.展開やAnsibleなどの外部ツールを使用して、コードを自動的に展開および更新します。

PHPアレイを反復しながら要素を交換する方法は?PHPアレイを反復しながら要素を交換する方法は?May 15, 2025 pm 08:30 PM

PHPでは、次の方法を使用して配列要素を横断および交換できます。1。foreachループと参照(&$値)を使用して要素を変更しますが、参照が副作用を引き起こす可能性があることに注意してください。 2。forループを使用して、インデックスと値に直接アクセスして、参照の問題を回避します。 3. array_map関数を使用して簡潔な変更を加えますが、キー名はリセットされます。 4. array_walk関数を使用して値を変更し、キー名を保持します。方法を選択する際には、パフォーマンス、副作用、キー名保持要件を考慮する必要があります。

PHPでISBN文字列を検証する方法は?PHPでISBN文字列を検証する方法は?May 15, 2025 pm 08:27 PM

PHPのISBN文字列の検証は、ISBN-10とISBN-13の2つの形式を処理できる関数を介して実装できます。 1.すべての非数字を削除します。 2。ISBN-10の場合、加重和の計算が使用され、結果を11。3で割ることができる場合は有効です。ISBN-13の場合、異なる重み付け和の計算を使用し、結果を10で割ることができる場合は有効です。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境