Encrypt Decrypt Bookmarklet

# はじめに
パスワードなどを暗号化、復号化するブックマークレットです。

![EncryptDecrypt.png](https://qiita-image-store.s3.amazonaws.com/0/83147/dc0a605b-a9ee-666a-6df1-0c1d05d901b5.png)

# Bookmarkletにする暗号復号フォーム

```html:暗号復号フォームのhtml
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha1.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/cipher-core.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/aes.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/pbkdf2.js"></script>
        <script type="text/javascript">
            function encrypt(){
                var encypt_text=document.getElementById("encypt-text").value;
                var pass=CryptoJS.enc.Utf8.parse(document.getElementById("encrypt-password").value);
                var salt=CryptoJS.lib.WordArray.random(128/8);
                var key=CryptoJS.PBKDF2(pass,salt,{keySize:256/32,iterations:100});
                var iv=CryptoJS.lib.WordArray.random(128/8);
                var options={iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7};
                var encrypted=CryptoJS.AES.encrypt(encypt_text,key,options);
                document.getElementById("transitmessage").value=salt.toString()+iv.toString()+encrypted.toString();
            }
            function decrypt(){
                document.getElementById("decrypted").value="";
                var transitmessage=document.getElementById("transitmessage").value;
                var salt=CryptoJS.enc.Hex.parse(transitmessage.substr(0,32));
                var iv=CryptoJS.enc.Hex.parse(transitmessage.substr(32,32));
                var encrypted=transitmessage.substring(64);
                var pass=CryptoJS.enc.Utf8.parse(document.getElementById("decrypt-password").value);
                var key=CryptoJS.PBKDF2(pass,salt,{keySize:256/32,iterations:100});
                var options={iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7};
                var decrypted=CryptoJS.AES.decrypt(encrypted,key,options);
                document.getElementById("decrypted").value=decrypted.toString(CryptoJS.enc.Utf8);
            }
        </script>
    </head>
    <body>
        <label for="encypt-text">暗号化するテキスト：</label><br />
        <textarea id="encypt-text" rows="8" cols="85">Hello</textarea><br />
        &nbsp;↓&nbsp;<label for="encrypt-password">暗号化パスワード：</label><br />
        &nbsp;↓&nbsp;<input id="encrypt-password" type="text" size="80" value="password" /><br />
        &nbsp;↓&nbsp;<input id="encrypt" type="button" value="暗号化する" onclick="encrypt()" /><br />
        <label for="transitmessage">暗号文：</label><br />
        <textarea id="transitmessage" rows="4" cols="85"></textarea><br />
        &nbsp;↓&nbsp;<label for="decrypt-password">復号パスワード：</label><br />
        &nbsp;↓&nbsp;<input id="decrypt-password" type="text" size="80" value="password" /><br />
        &nbsp;↓&nbsp;<input id="decrypt" type="button" value="復号する" onclick="decrypt()" /><br />
        <label for="decrypted">復号された平文：</label><br />
        <textarea id="decrypted" rows="8" cols="85"></textarea>
    </body>
</html>
```

上記htmlに次の変更を行い、Bookmarkletに変換。

- タブ（スペース4つ）を削除
- スペースを%20に置換
- 改行を削除
- 「`javascript:w=window.open('','Links','scrollbars,resizable,width=640,height=550');w.document.write('`」と「`');`」を先頭と末尾に追加

```js:変換後のBookmarklet
javascript:w=window.open('','Links','scrollbars,resizable,width=640,height=550');w.document.write('<!DOCTYPE%20html><html><head><meta%20charset="utf-8"/><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js"></script><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha1.js"></script><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac.js"></script><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.js"></script><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/cipher-core.js"></script><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/aes.js"></script><script%20src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/pbkdf2.js"></script><script%20type="text/javascript">function%20encrypt(){var%20encypt_text=document.getElementById("encypt-text").value;var%20pass=CryptoJS.enc.Utf8.parse(document.getElementById("encrypt-password").value);var%20salt=CryptoJS.lib.WordArray.random(128/8);var%20key=CryptoJS.PBKDF2(pass,salt,{keySize:256/32,iterations:100});var%20iv=CryptoJS.lib.WordArray.random(128/8);var%20options={iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7};var%20encrypted=CryptoJS.AES.encrypt(encypt_text,key,options);document.getElementById("transitmessage").value=salt.toString()+iv.toString()+encrypted.toString();}function%20decrypt(){document.getElementById("decrypted").value="";var%20transitmessage=document.getElementById("transitmessage").value;var%20salt=CryptoJS.enc.Hex.parse(transitmessage.substr(0,32));var%20iv=CryptoJS.enc.Hex.parse(transitmessage.substr(32,32));var%20encrypted=transitmessage.substring(64);var%20pass=CryptoJS.enc.Utf8.parse(document.getElementById("decrypt-password").value);var%20key=CryptoJS.PBKDF2(pass,salt,{keySize:256/32,iterations:100});var%20options={iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7};var%20decrypted=CryptoJS.AES.decrypt(encrypted,key,options);document.getElementById("decrypted").value=decrypted.toString(CryptoJS.enc.Utf8);}</script></head><body><label%20for="encypt-text">暗号化するテキスト：</label><br%20/><textarea%20id="encypt-text"%20rows="8"%20cols="85">Hello</textarea><br%20/>&nbsp;↓&nbsp;<label%20for="encrypt-password">暗号化パスワード：</label><br%20/>&nbsp;↓&nbsp;<input%20id="encrypt-password"%20type="text"%20size="80"%20value="password"%20/><br%20/>&nbsp;↓&nbsp;<input%20id="encrypt"%20type="button"%20value="暗号化する"%20onclick="encrypt()"%20/><br%20/><label%20for="transitmessage">暗号文：</label><br%20/><textarea%20id="transitmessage"%20rows="4"%20cols="85"></textarea><br%20/>&nbsp;↓&nbsp;<label%20for="decrypt-password">復号パスワード：</label><br%20/>&nbsp;↓&nbsp;<input%20id="decrypt-password"%20type="text"%20size="80"%20value="password"%20/><br%20/>&nbsp;↓&nbsp;<input%20id="decrypt"%20type="button"%20value="復号する"%20onclick="decrypt()"%20/><br%20/><label%20for="decrypted">復号された平文：</label><br%20/><textarea%20id="decrypted"%20rows="8"%20cols="85"></textarea></body></html>');
```

本ブックマークレットにより、安全にパスワードを運用できます。