Can this secure, random generator be improved? This random generator uses cryptographically secure numbers/chars instead of Math.random(). The Javascript code with jQuery works well but I affect clean code ;) It would be great if you could help me to optimize the code (e.g. in speed).

(function () {
    var $length, $result, $new, $chars;

    $(document).ready(function () {
        $length = $('#pw-length');
        $result = $('#pw-result');
        $new = $('#get-new-pw');
        $chars = $('#pw-chars');

        // display the result on page load
        getRandomString();
        // generate new password
        $new.click(function () {
            getRandomString();
            return false;
        });

        // allow only numbers in the length-input-field
        $length.on('keyup focusout', function () {
            $length.val($length.val().replace(/[^0-9]/g, ''));
        });
    });

    function randomString(length) {
        var charset = $chars.val(),
            length = parseInt($length.val()),
            i,
            result = "";

        // First we're going to try to use a built-in CSPRNG
        if (window.crypto &amp;&amp; window.crypto.getRandomValues) {
            values = new Uint32Array(length);
            window.crypto.getRandomValues(values);

            for (i = 0; i &lt; length; i++) {
                result += charset[values[i] % charset.length];
            }
        }

        // IE calls it msCrypto
        else if (window.msCrypto &amp;&amp; window.msCrypto.getRandomValues) {
            values = new Uint32Array(length);
            window.msCrypto.getRandomValues(values);

            for (i = 0; i &lt; length; i++) {
                result += charset[values[i] % charset.length];
            }
        }

        // -&gt; No built-in functionality -&gt; use the function Math.random()
        else {
            for (i = 0; i &lt; length; i++) {
                result += charset[Math.floor(Math.random() * charset.length)];
            }
        }

        return result;
    }

    // Display the result
    function getRandomString() {
        $result.html(randomString(10));
    }
}());


I also uploaded it here for testing.
And of course the corresponding HTML:

&lt;input type="text" id="pw-chars" value="AaBbCcDdEeFfGgHhiJjKkLMmNnoPpQqRrSsTtUuVvWwXxYyZz23456789!?$%#&amp;@^+-~*=_.,:;()" /&gt;
&lt;input type="text" id="pw-length" value="10" /&gt;
&lt;button id="get-new-pw"&gt;New&lt;/button&gt;

&lt;div id="pw-result"&gt;&lt;/div&gt;
I agree with @Bobby. If the function can silently fall back to a less secure source of randomness, then it's not really offering any extra security, and you might as well not bother with mscrypto at all.

Verbesserungsvorschlag:

function randomString(length, allowRandomSourceFallback) {
    ...
}


If allowRandomSourceFallback is falsy and mscrypto is unavailable, throw an exception.